vmstat: Spot I/O Wait and Swapping in CI
vmstat prints CPU, memory, swap, and I/O counters at an interval, revealing whether a slow runner is CPU-bound, I/O-bound, or swapping itself to death.
A build that is slow without an obvious CPU hog is often swapping or waiting on disk. vmstat’s si/so and wa columns distinguish those causes at a glance.
What it does
vmstat <interval> samples system-wide stats each interval. Key columns: si/so are swap-in/swap-out (KB/s; nonzero means active swapping), wa is the percentage of CPU time waiting on I/O, b is processes blocked on I/O, and us/sy/id are user/system/idle CPU. The first row is an average since boot; ignore it and read the rest.
Common usage
vmstat 2 # sample every 2 seconds
vmstat 2 5 # 5 samples, then exit
vmstat -s # one-shot memory/event totals
vmstat -d # per-disk I/O statisticsOptions
| Field / flag | What it does |
|---|---|
| <delay> [count] | Sample every delay seconds, count times |
| si / so | Swap in / out per second (>0 = thrashing) |
| wa | CPU percent waiting on I/O |
| b | Processes in uninterruptible sleep (blocked) |
| -s | Dump memory and event totals |
| -d | Per-disk statistics |
In CI
Run vmstat 2 10 during a slow step. High us with low wa is genuinely CPU-bound (more cores help). High wa with a high b count is I/O-bound (faster disk or fewer parallel writers help). Any sustained si/so means the runner is out of RAM and swapping, which destroys performance and often precedes an OOM kill.
Common errors in CI
Reading the first vmstat row as "current" is a common mistake; it is the since-boot average and is usually misleadingly calm. In a container, vmstat reflects the host, so swap and I/O may be other tenants’ activity, not yours. Persistent wa near 100 with the build stalled points at disk, not CPU.