CPU Steal Time Explained: Why Your VPS Is Slow When Nothing's Running
Steal time (%st in top) is time your virtual machine wanted the CPU but the hypervisor gave it to someone else. How to measure it with top, vmstat and mpstat, what levels are normal, how it differs from high load, why shared vCPUs suffer from it, and what to do when it's hurting your app.
Your app on a VPS is slow. CPU usage looks moderate, nothing unusual is running, and yet requests take twice as long as last week. Look for one small number in top: st, CPU steal time.
What steal time is
A VPS is a virtual machine. Its virtual CPUs (vCPUs) are scheduled by the hypervisor onto the host's physical CPU cores, which are shared with other customers' VMs. (What Is a VPS?, How KVM Virtualization Works)
Steal time is the percentage of time your VM had work ready to run, but the hypervisor was running someone else. Your process wasn't waiting for disk or network — it was waiting for a physical CPU that was busy with a neighbour.
How to see it
top — the CPU line:
%Cpu(s): 22.1 us, 4.3 sy, 0.0 ni, 51.2 id, 0.4 wa, 0.0 hi, 0.3 si, 21.7 st
21.7 st means over a fifth of the time, your VM was ready but not allowed to run. That's bad.
vmstat — the st column, sampled every second:
vmstat 1 10
mpstat (from the sysstat package) — per vCPU:
mpstat -P ALL 1 5
Look at %steal. Watch over minutes, not one snapshot — steal comes and goes with your neighbours' activity. (Check Disk Space and Memory on Linux)
What's normal?
| Steal | Meaning |
|---|---|
| 0–2% | Normal on shared vCPUs |
| 2–10% | Noticeable for latency-sensitive apps |
| 10%+ sustained | The host is oversubscribed; performance is suffering |
On dedicated vCPU plans, steal should be essentially zero.
Steal vs high load
| Symptom | Likely cause |
|---|---|
High us/sy, low st |
Your own code is using the CPU — profile it |
High wa |
Waiting on disk I/O |
High st, moderate us |
Noisy neighbours / oversubscribed host |
| Low everything, still slow | Waiting on network, database locks, or external APIs |
Steal also confuses metrics: your app may report lower CPU usage than it "needs", because it simply wasn't scheduled. (Why Is My Website Slow?, Node.js Event Loop Lag)
Burstable instances look like steal
On "burstable" cloud instances (CPU credits), once credits run out the hypervisor throttles you to a baseline — which also shows up as steal. If steal appears after sustained heavy use and disappears after a quiet period, you're probably out of credits rather than suffering neighbours.
What to do about it
- Confirm it's sustained, not a short spike. Log
vmstatfor an hour. - Ask the provider to migrate you to a less busy host — many will, and some VMs can be live-migrated. Recreating or resizing the server often lands it elsewhere too.
- Move to dedicated vCPUs for production apps where latency matters. They cost more but remove the lottery.
- Scale vertically or horizontally if you're also genuinely CPU-bound. (Horizontal vs Vertical Scaling)
- Reduce CPU work — caching and efficient queries make you less sensitive to steal. (Caching Explained)
Why it matters more for databases and agents
Databases and coding agents (builds, test suites, type checking) are CPU-hungry and latency-sensitive. A test suite that takes 40 seconds on a quiet host can take 90 on a noisy one, and your coding agent waits for every run. Consistent CPU is worth paying for when an agent works on the box all day.
The summary
- Steal (
st) = your VM was ready to run but the host gave the CPU to someone else. - Check with
top,vmstat 1ormpstat; sustained 10%+ is a problem. - Fix by moving hosts, switching to dedicated vCPUs, or reducing CPU demand.
EasySpawn runs each server as its own VM with resources sized for development workloads, and Claude Code can check vmstat and profile your app when things feel slow. See how it works or join the waitlist.
Related: Containers vs Virtual Machines · Linux Pressure Stall Information · Hetzner vs AWS · Load Testing Your App
Keep reading
What Is OpenTelemetry? Traces, Metrics and Logs Explained
OpenTelemetry is the open standard for collecting traces, metrics and logs from your app and sending them to any observability backend. The three signals, spans and context propagation, auto-instrumenting a Node.js app, the Collector, backends, LLM and agent tracing, and what a small team actually needs.
"No Space Left on Device": Finding and Freeing Disk Space on a Server
When a server's disk fills up, databases stop writing, deploys fail and apps crash with ENOSPC. How to find what's using space with df and du, the usual culprits (logs, Docker, journald, old releases, deleted-but-open files), inode exhaustion, and how to stop it happening again.