Measuring Sustained CPU Steal on a VPS and Choosing the Right Fix

CPU steal is the percentage of time your virtual machine wanted to run but the hypervisor gave the physical CPU core to another tenant. On shared VPS infrastructure it is the most common cause of “the server feels slow but nothing is using the CPU” complaints. Unlike memory pressure or a misconfigured application, steal is invisible in htop unless you know which column to read, and it cannot be fixed with more RAM or a faster framework. This guide explains how to measure steal reliably, what the numbers mean, and what actually reduces it.

How CPU steal shows up in your metrics

On Linux, the kernel accounts steal time in the st column of top, vmstat, and mpstat. It appears whenever the hypervisor schedules a different virtual machine on the physical core your vCPU depends on. The telltale signature is high st with low us and sy: the CPU is not busy doing your work — it simply was not given time to do it.

ToolCommandWhat to look at
top / htoptop -d 2st column; sustained >5% while load is high
vmstatvmstat 1second st column (percentage of total CPU)
mpstatmpstat -P ALL 1per-vCPU %steal; one hot vCPU points to a single noisy neighbor
sarsar -u 1 5%steal historical trend if sysstat is installed
pressurecat /proc/pressure/cpusome total= value is real stall, not just steal

A single reading proves nothing. Steal of 15% for two seconds during a backup window is normal; steal of 8% sustained for twenty minutes across every sample is a capacity problem. Sample with sar or a loop, and compare against the same hours on the previous day before concluding anything.

# 60 samples, print steal only
for i in $(seq 60); do
  mpstat 1 1 | awk '/Average/ {print $3"% us  "$6"% steal"}'
done

Separating steal from your own CPU use

The critical distinction is whether your workload is the cause. If us plus sy is low and st is high, the hypervisor is starving you. If us is high and st is low, your own processes are simply busy and the fix is at the application layer. A workload that saturates its own vCPUs can also trigger more steal because the hypervisor is more likely to preempt a busy guest.

Run this comparison on a schedule so you have a baseline before the complaint arrives:

vmstat 1 10 | tail -n +2 | awk '{print "us="$13" sy="$14" id="$15" wa="$16" st="$17}'

What actually reduces steal

  • Fewer vCPUs, not more. On a contended host, adding vCPUs multiplies the number of cores the scheduler can preempt you on. A 2-vCPU plan often shows less steal than an 8-vCPU plan on the same host.
  • Move to a dedicated-vCPU tier. Pinned or dedicated cores carry a lower oversubscription ratio. This is the only real fix when you are genuinely starved.
  • Reduce your own CPU demand. Cache aggressively, cut polling intervals, and profile hot paths so you need fewer cycles.
  • Migrate hosts. Live migration to a less-loaded physical node sometimes helps, but it can also land you on a worse neighbor.
  • Check the provider’s oversubscription. Some plans advertise “shared” cores at 4:1; others run 12:1. The ratio predicts steal far better than the clock speed on the spec sheet.

Turning steal into a decision

Keep a rolling log of steal and correlate it with user-visible latency. If p95 response time tracks steal, you have a hosting problem and should move to guaranteed CPU. If latency spikes with stable steal, the bottleneck is inside your stack and no amount of extra vCPU will help.

# log steal every 5 minutes for a week
echo '*/5 * * * * mpstat 1 1 | awk "/Average/ {print strftime(\"%F %T\"), \$6}" \
  >> /var/log/steal.log' | crontab -

Measure first, then act: steal is one of the few VPS performance problems where the diagnosis is cheap and unambiguous once you sample over time. When the numbers show genuine starvation, choose a plan with dedicated CPU rather than throwing more shared cores at it — that is the difference between fixing the problem and paying for a smaller version of the same one. Review our VPS plans with dedicated or pinned cores when the log proves you are starved, and compare managed versus unmanaged options if you would rather not run the sampling yourself.

A note on cloud burst and credit-based plans

Some providers sell “burstable” CPU plans where a baseline is guaranteed and short bursts are allowed up to a ceiling. These plans do not show classic steal — instead they throttle you by reducing the CPU quota, which appears as us and sy falling while wall-clock work still takes longer. If your throughput drops without st rising, check the provider’s CPU credit counter before concluding the host is contended. The two problems look identical to a user and completely different in the metrics, which is why sampling both steal and effective throughput matters.

Building a steal baseline you can trust

Collect data when the server is healthy, not just when it is slow. A baseline taken during quiet hours tells you what “normal” looks like on your host, so a reading of 3% during peak traffic is immediately interpretable. Tag samples by hour of day and day of week; many hosts concentrate contention in business hours or during a specific tenant’s nightly batch, and a pattern across time is far more actionable than any single spike.

Leave a Reply