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.
| Tool | Command | What to look at |
|---|---|---|
| top / htop | top -d 2 | st column; sustained >5% while load is high |
| vmstat | vmstat 1 | second st column (percentage of total CPU) |
| mpstat | mpstat -P ALL 1 | per-vCPU %steal; one hot vCPU points to a single noisy neighbor |
| sar | sar -u 1 5 | %steal historical trend if sysstat is installed |
| pressure | cat /proc/pressure/cpu | some 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
You must be logged in to post a comment.