vmstat (virtual memory statistics) prints one compact line per interval covering processes, memory, swap, disk I/O and CPU. When a server is slow, it’s often the fastest way to tell what kind of problem it is: CPU, memory pressure, or disk.

Run it with an interval

vmstat 1 10        # every second, 10 times
vmstat -w 1        # wide output, easier to read
vmstat -S M 1      # memory in MB

Ignore the first line. It shows averages since boot. The following lines show the current state.

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 3  0      0 412000  81000 2210000    0    0     5    40  900 1500 35  5 59  1  0
 9  4 512000  35000  12000  180000  420  910  6800  2100 4100 8800 20 10  5 60  5

The first data line is a healthy server. The second is in trouble.

The columns

procs

  • r — runnable processes, either running or waiting for a CPU. Consistently above the number of cores (nproc) means CPU saturation.
  • b — processes blocked in uninterruptible sleep, usually waiting on disk I/O. Anything consistently above 0 deserves a look.

memory (KiB by default)

  • swpd — swap in use.
  • free — unused RAM. Low is normal, because Linux uses spare RAM as cache.
  • buff / cache — buffers and page cache, which can be reclaimed when apps need memory.

Don’t judge memory by free alone. See free command.

swap

  • si — swapped in from disk per second.
  • so — swapped out to disk per second.

These matter more than swpd. Some swap usage with si/so at 0 is harmless: idle pages were moved out once. Continuous non-zero si and so means the server is short of RAM and is thrashing. Everything gets slow.

io

  • bi — blocks read from disk per second.
  • bo — blocks written per second.

system

  • in — interrupts per second.
  • cs — context switches per second. Very high values with high sy can point to too many threads or processes competing.

cpu (% of total CPU time)

  • us — user code (your apps).
  • sy — kernel.
  • id — idle.
  • wa — waiting for I/O.
  • st — steal, time the hypervisor gave to other VMs. Relevant on a VPS.

Reading patterns

Pattern Diagnosis
r > cores, us high, id ≈ 0 CPU-bound. Find the process with top, then optimise or scale
b > 0, wa high, bi/bo high, si/so = 0 Disk-bound. Check iostat, slow queries, backups
si/so > 0 continuously, free low, wa high Out of memory and swapping. Reduce memory use or add RAM
sy high, cs very high Too many workers or threads, or kernel contention
st consistently > 5–10% Host CPU contention. Contact the provider or consider a dedicated server
Everything low but the site is slow Look elsewhere: the network, an external API, the database on another host, app locks

The second line in the example above shows memory exhaustion: si/so of hundreds of KB/s, little free memory, a tiny cache, and 60% wa, with 4 processes blocked. Fix the memory problem and the I/O wait disappears. That might mean lowering PHP-FPM max_children or the MySQL buffer pool, or upgrading the plan. See PHP-FPM tuning and MySQL buffer pool.

Other vmstat modes

vmstat -s            # memory and event counters since boot
vmstat -d            # per-disk statistics
vmstat -t 1          # add a timestamp to each line (good for logging)
vmstat -a 1          # active/inactive memory instead of buff/cache

Log during an incident window for later analysis:

vmstat -tw 5 720 > /tmp/vmstat-$(date +%F).log     # one hour at 5 s intervals

vmstat in the toolbox

Question Tool
What kind of bottleneck? vmstat
Which process? top, htop, ps
Which disk, how busy, what latency? iostat
Which process is doing the I/O? iotop, pidstat -d 1
History over days sar (sysstat) or a monitoring tool

vmstat comes with the procps package, which is installed everywhere.

Quick reference

Column Watch for
r > CPU cores, sustained
b > 0, sustained
si / so Any continuous activity
wa > 10–20%
st > 5–10% on a VPS
id Near 0 with high r

Related: load average and top.

  • Linux
  • Performance
  • Monitoring