SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor ・更新日 2026-10-19

VPSのCPU steal timeとnoisy neighbourの見分け方

VPSのCPU steal timeは、実行可能なのに他のゲストへCPUを奪われた時間です。vmstatのst列を読み、自身の過負荷とnoisy neighbourを切り分けます。

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, August 7, 2026.

CPU steal time が実際に測定するもの

CPU steal time は、仮想 CPU が実行可能な状態で待機すべき処理もなく、ハイパーバイザーが物理コアを別のゲストに割り当てていた時間の割合です。処理はキューに入っていました。コアは別の場所で使われていました。Linux はこのサイクルを個別にカウントし、st として報告します。これにより、「サーバーがビジーである」状態と「実行の順番を待っている」状態を区別できます。

この違いが、カウンターが存在する理由です。プロセス自身が CPU 上で消費した時間は、us (user) または sy (system) として報告されます。タスクがストレージ処理でブロックされている時間は、wa (I/O wait) として報告されます。vCPU (virtual CPU) が実行可能で、run queue 上にあり、I/O の処理待ちもなく、それでも実行されていない場合は、st として報告されます。スケジューリングの判断は、ホスト上の、あなたのサーバーより 1 層下で行われるため、サーバー内部の処理ではこの状態を解消できません。

これは、1 台の物理マシンを VPS 間で共有する仕組みから直接生じます。通常の原因は同居する別のゲストです。同じノード上の別のゲストが高負荷で動作しているため、ホストがコアを複数のゲストに分配します。見落とされやすい原因もあります。多くのプロバイダーは、共有 vCPU に物理コアの一部だけを使用できる上限を設定しています。複数のハイパーバイザーでは、その制限による待機時間がゲスト内で steal として計上されます。したがって、st の値が高い場合、コアが自分に割り当てられていなかったことは分かります。ただし、誰がコアを使用していたかまでは常に分かりません。

steal 値の出所

カーネルはホストを認識できないため、steal を単独で測定できません。ハイパーバイザーが値を通知します。KVM では、ホストがゲストと共有するページに vCPU ごとのカウンターを書き込みます。ゲストは、カーネルが CONFIG_PARAVIRT_TIME_ACCOUNTING を有効にしてビルドされている場合に、その値を集計します。すべてのディストリビューションカーネルで有効になっています。Xen は runstate area を通じて同じ値を報告します。合計値は、次の 1 か所から userspace に渡されます。

head -1 /proc/stat

この cpu の行には、ブート後の USER_HZ 単位のカウンターが 10 個、次の順序で格納されています。user、nice、system、idle、iowait、irq、softirq、steal、guest、guest_nice です。steal は、ラベルの後にある 8 番目の値です。以下の各ツール、vmstat、top、mpstat、およびすべての Prometheus exporter は、同じフィールドを読み取り、2 つのサンプルから割合を計算します。

最も重要な点は 1 つです。ハイパーバイザーがカウンターをエクスポートしない場合、このフィールドは常に 0 のままです。そのため、この値を基にするすべてのツールは、ホストが過負荷でも正常な 0.0 と報告します。KVM と Xen はこの値をエクスポートします。その他のプラットフォームでは VMware や Hyper-V など、steal が表示されるかどうかは、ホストが公開する情報とゲストカーネルの対応状況によって決まります。そのため、値が 0 のままでも、それだけでは何も証明できません。0 を信頼する前に、プラットフォームを確認してください。

systemd-detect-virt

このコマンドは、kvm、xen、vmware、microsoft などのプラットフォーム名を表示します。ベアメタルでは none と表示されます。コンテナ内では、lxc、docker、podman など、基盤のマシンではなくコンテナのランタイムが表示されます。kvm では、0 はホストが適切にリソースを割り当てていることを示す実際の証拠です。フィールドに一度も値が書き込まれないプラットフォームでは、0 は何の証拠にもなりません。その場合は、実際の処理の所要時間を測定して競合を判断する必要があります。

VPS で CPU steal time を確認する方法

vmstat は procps パッケージに含まれています。ほぼすべての Ubuntu および Debian の VPS イメージには最初から入っていますが、一部の最小構成のコンテナイメージには含まれていません。そのため、依存する前にインストールしてください。

sudo apt-get update
sudo apt-get install -y procps
vmstat --version
vmstat 1 5

vmstat --version を実行すると、vmstat from procps-ng 4.0.4 のような行が表示されます。これが表示されれば、ツールはインストール済みで、実際のカーネルカウンターを読み取っています。続いて vmstat 1 5 を実行すると、5 件のレポートが表示されます。最初のレポートは起動後の平均値で、後続の4件は1秒間隔のサンプルです。

procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st gu
 1  0      0 3216484  98304 1284360    0    0     4    18   62  110  3  1 96  0  0  0
 2  0      0 3216232  98304 1284360    0    0     0     0  248  431  6  2 84  0  8  0

右側の cpu ブロックにある st 列を確認します。現在の procps-ng ビルドでは、その後ろに KVM ゲスト時間用の gu 列が表示されるため、st は右から2番目です。リリースによってこの位置が変わっているため、位置ではなくヘッダー名で列を確認してください。

正確に読み取るには、2つの点に注意します。最初のデータ行は起動後の平均値なので無視し、その後の行を読みます。また、steal はバースト状に発生するため、1回のサンプルだけでは測定になりません。vmstat 1 61 を実行すると、起動後の行に続いて1秒間隔のサンプルが60件表示されます。結論を出す前に、1分間全体を確認してください。

top は、%Cpu(s) のサマリー行に st と示されるフィールドで、同じ値を報告します。

%Cpu(s):  6.2 us,  2.1 sy,  0.0 ni, 83.9 id,  0.0 wa,  0.0 hi,  0.3 si,  7.5 st

CPU ごとの詳細を確認するには、sysstat を追加します。

sudo apt-get install -y sysstat
mpstat -P ALL 1 5

mpstat は CPU ごとに1行を表示し、%steal 列で各 vCPU が影響を受けているか、一部の vCPU だけが影響を受けているかを確認できます。サポートチケットに必要な履歴を取得する場合は、画面上で読み取るのではなく、サンプルを保存してください。

date -u | tee -a ~/steal.log
mpstat -P ALL 1 5 | tee -a ~/steal.log

疑わしい時間帯に cron からこれを実行してください。保存したファイルがあれば、「昨夜は遅く感じた」とプロバイダーに伝えるだけでなく、正確な10分間のデータを提示できます。

steal の値は何を意味しますか?

  • 安定して 0.0。 正常な状態です。または、プラットフォームが steal をまったく報告していない可能性があります。問題ないと判断する前に、systemd-detect-virt で確認してください。
  • 数秒間続く数パーセントの急上昇。 共有ノードでは正常です。近隣のユーザーがビルドを開始したか、ホストがバックアップを実行しています。
  • 共有プランで継続する 1~5 パーセント。 想定範囲です。料金には共有 CPU であることが反映されています。
  • 継続する 5~10 パーセント。 測定可能な速度低下が発生しています。証拠の記録を開始し、数日間にわたって同じ時間帯を比較してください。
  • 一度に数時間、10 パーセントを超える。 ノードがワークロードに対して過負荷になっているか、プランの CPU 制限が適用されています。一部のプロバイダーでは、その制限を steal として報告します。サポートへの問い合わせや移行を検討すべき水準です。

これらの範囲は仕様ではなく、読み取りの目安として扱ってください。共有プランでは、steal の値を保証するプロバイダーがないためです。実行している処理と照らし合わせて判断してください。夜間のバッチジョブであれば、steal が 15 パーセントあっても影響が現れないことがあります。一方、レイテンシーに敏感なサービスでは、平均値が問題に見える前から p99 に影響が現れます。そのため、トレーディングボットなどのレイテンシーに敏感なワークロードは専用コアで実行してください。

スティール時間のコストはどの程度ですか?

計算は簡単です。CPU 時間のうち s の割合が奪われると、一定量の CPU を必要とするジョブは、実時間で 1 / (1 - s) 倍の時間がかかります。60 秒の CPU 時間を必要とするジョブの場合:

グラフWall clock time for a job needing 60 seconds of CPU
このグラフのデータ
[
  {
    "steal_percent": 0,
    "wall_clock_seconds": "60.0"
  },
  {
    "steal_percent": 3,
    "wall_clock_seconds": "61.9"
  },
  {
    "steal_percent": 8,
    "wall_clock_seconds": "65.2"
  },
  {
    "steal_percent": 15,
    "wall_clock_seconds": "70.6"
  },
  {
    "steal_percent": 25,
    "wall_clock_seconds": "80.0"
  },
  {
    "steal_percent": 40,
    "wall_clock_seconds": "100.0"
  }
]

3 パーセントの場合、一般的な共有プランで見られる値ですが、そのジョブにかかる時間は 61.9 秒です。60.0 秒ではありません。この程度でチケットを起票する人はいません。8 パーセントでは 65.2 秒です。40 パーセントになると、同じジョブに 100.0 秒かかり、以前は処理できていたキューが逆に増え始めます。

これらは測定値ではなく、計算値です。このモデルでは、実行可能なスレッドが 1 つだけあり、区間全体にわたってスティール時間が均等に発生すると仮定しています。実際のサービスでは、この曲線より深刻に感じることがよくあります。リクエストの処理中に CPU 時間を奪われると、その遅延を、そのリクエストの完了を待つすべての処理が再び受けるためです。計算式ではなく自分の値を得るには、静かな時間帯と負荷の高い時間帯に VPS のベンチマークを実行し、両方の時間帯について st を記録します。

これは steal か、それとも別の現象か

steal は、ほかの症状と混同しやすい指標です。同じ vmstat 行にあるカウンターをまとめて確認してください。

  • st が高く、r と us が低いままの場合、ホストがコアを割り当てていません。これが steal です。
  • r が vCPU 数を大きく上回り、us が高く、st がほぼ 0 の場合、自分の CPU で処理できる量を超える作業を実行しています。r と nproc の出力を比較してください。これは隣接するテナントが原因ではなく、自分の環境での過剰なオーバーサブスクリプションです。
  • wa が高く、st がほぼ 0 の場合、タスクがストレージ処理でブロックされています。これは別の問題であり、対処方法も異なります。
  • ロードアベレージが高い一方で st と us がどちらも低い場合、ロード値には割り込み不能なタスクも含まれます。そのため通常は CPU ではなく、停止したデバイスやハングしたネットワークマウントが原因です。

バースト可能なプランについては、別途確認が必要です。アイドル時にクレジット残高が増え、負荷が高いときに減少します。残高を使い切ると、プロバイダーはベースラインの速度に制限します。プラットフォームによっては、このスロットリングが steal として報告されます。別のプラットフォームでは、ゲスト OS 内から確認できず、単に 1 秒あたりに割り当てられる CPU サイクルが少なくなります。隣接するテナントが原因だと判断する前に、プランの説明を確認してください。

コンテナで steal time が表示されない理由

Steal は仮想マシンの特性であり、その内部で実行されるコンテナの特性ではありません。自分の VPS 上の Docker コンテナはホストの /proc を共有するため、コンテナ内で読み取った st の値は VPS の steal です。これは必要な値です。VPS として提供されるコンテナベースの仮想化は、動作が異なります。lxcfs が設定されている場合、コンテナ内の /proc/stat は cgroup のアカウンティングから合成されるため、steal は仕様上 0 になります。コンテナ内部だけからメトリクスを収集する監視基盤では、物理マシンが下層でリソース不足に陥っていても、変化のない穏やかな 0 として表示されることがあります。

コンテナ内で同じ意味を持つカウンターは、CPU quota によるスロットリングです。cgroup v2 では次のようになります。

cat /sys/fs/cgroup/cpu.stat

nr_throttled は、グループが CPU quota に到達した強制適用期間の回数を数え、throttled_usec はその間に停止していた時間の合計を示します。nr_throttled の増加は、プロセスが実行可能でありながら実行されていないことを意味します。これは steal と同じ状態ですが、自分で設定した制限が原因です。ホストを疑う前に、自分の制限を確認してください。特に、compose ファイルで CPU limits を設定して VPS 上の Docker でサービスを実行している場合は注意が必要です。階層化された仮想化では、時間が失われる場所がさらに増えます。VPS 内の VM は、自身の steal に加えて、独自のスケジューリング遅延も受けるためです。VPS 上で nested virtualisation を実行している場合は、この点を考慮してください。

継続的に steal が発生する場合の対処

guest 内の設定では steal を解消できません。判断を行う scheduler は guest の外部で動作しているためです。kernel を更新しても状況は変わりません。Linux kernel 7.2 で追加された cache aware scheduling は、実際に割り当てられた core 間でタスクを再配置するだけです。隣接する guest がすでに消費した CPU サイクルを取り戻すことはできません。実行できる対策は 4 つです。

まず証拠を収集します。 UTC の timestamp、各エピソードの継続時間、発生頻度を記録します。mpstat で影響を受けている vCPU が 1 つだけか、すべてかも確認します。1 週間分のサンプルをログに記録したほうが、スクリーンショット 1 枚より有用です。

そのデータを添えて ticket を起票します。 次の 2 点を直接質問します。該当する時間帯にこの node が oversubscribed になっているか、また instance を移動できるかです。vmstat の出力と正確な時刻を貼り付けます。provider は再現可能な時間帯の情報があると対応しやすくなります。「server が遅い」とだけ書いた ticket には、その時間帯を尋ねる返信が来ます。どこまでの作業を provider に任せられるかは、managed VPS と unmanaged VPS の実務上の違いの 1 つです。

migration を依頼します。 guest を負荷の低い node に移す作業は、provider にとって通常の対応です。通常は短時間の reboot で完了します。費用のかからない対策であり、1 つの node に複数の負荷の高い隣接 guest が同時に配置されているという、よくある状況を解消できます。

専用 CPU を購入して競合をなくします。 dedicated vCPU plan では instance 用の CPU capacity が予約されます。provider によって、full core または full hardware thread が割り当てられます。そのため隣接する guest が CPU サイクルを奪うことがなくなり、counter は 0、または 0 に極めて近い値で推移します。ただし、hypervisor 自身のハウスキーピングによって、わずかな値が残る場合があります。月額料金は高くなりますが、負荷の変動を許容できない workload には適切な選択です。それでも不十分な場合、または memory bandwidth も専有したい場合は、VPS ではなく dedicated server が次の選択肢です。

これらの対策を待つ間も、steal による影響を減らします。vCPU 数より少ない worker thread 数で実行してください。core を取得できない thread を増やしても、context switch が増えるだけだからです。batch 処理を node が静かな時間帯に移します。その時間帯は、収集したログから判断できます。その後、同じ時間帯に同じ command で再度測定します。推測ではなく、変更の効果を確認できます。

FAQ

VPS における正常な CPU steal time とはどの程度ですか?

共有プランの場合、短時間のスパイクや 5 パーセント未満の持続的な値は一般的です。これは、共有 CPU がホストの物理コアを複数のゲストで分割しているためです。数時間にわたって 2 桁の数値が続く場合は異常であり、サポートチケットを発行すべきです。専用 vCPU プランでは、期待される値は 0.0 または 0.0 に非常に近い値です。ハイパーバイザーの管理処理がわずかなリソースを消費することがあるためです。これを超える値が持続する場合は報告すべき障害です。数値の判断は自身のワークロードに基づいて行ってください。夜間のバッチ処理であれば許容できる steal も、遅延に敏感な API では許容できない場合があります。

プランをアップグレードすれば高い steal time は解消されますか?

それだけでは解消されません。同じ共有ノード上で vCPU 数を増やしても、競合する物理コアに対してより多くの仮想 CPU が競合するだけとなり、パーセンテージは変わらない可能性があります。steal をほぼ完全に取り除くには、専用 CPU の割り当てを受けるか、負荷の低いノードへ移行する必要があります。混雑したマシンでの割り当て量を増やしても、混雑したマシンであることに変わりはありません。

動作が明らかに遅いのに、VPS の steal time が 0 と表示されるのはなぜですか?

2 つの一般的な理由があります。1 つ目は、ハイパーバイザーがカウンターを全く出力していないケースです。これはホストやゲストカーネルの組み合わせにより一部のプラットフォームで発生し、ホスト側の状況に関わらず値は 0 のままとなります。systemd-detect-virt を実行して、利用しているプラットフォームを確認してください。2 つ目は、ボトルネックが別の場所にあるケースです。wa でストレージの待機時間を確認し、r と nproc を比較して自身の過負荷を確認してください。また、コンテナ内の /sys/fs/cgroup/cpu.stat を読み取り、クォータによる制限が発生していないか確認してください。

サーバー内部から steal time を減らすことはできますか?

ゲスト内部からホストのスケジューリングを変更することはできません。影響を軽減することしかできません。ワーカースレッドの数を vCPU 数よりも少なく設定し、利用できないコアを待機する実行キューの負荷を減らしてください。バッチ処理はノードが空いている時間帯に移動させてください。結果をキャッシュし、CPU を必要とするリクエスト自体を減らすことも有効です。steal を根本的に解消するノードの移行や専用コアの利用は、プロバイダー側でしか行えません。

この記事は役に立ちましたか?