vmstat Command in Linux: Complete Guide to Virtual Memory Statistics and Parameters

vmstat command in Linux and it perimeters

There’s a particular moment every sysadmin has: a server is “slow,” nobody can say exactly why, and top just shows a wall of numbers refreshing every two seconds without telling a clear story. That’s usually when I reach for vmstat. It’s not flashy, it doesn’t have colors or a fancy TUI, but it gives me the one thing I actually need in that moment — a clean, columnar snapshot of what the kernel is doing across processes, memory, swap, I/O, and CPU, all in one line I can read at a glance.

This guide covers vmstat from “what is this tool” all the way to using it for serious performance diagnosis on production systems.

What Is vmstat?

vmstat stands for virtual memory statistics. It’s part of the procps (or procps-ng) package on most distributions, and like most of the tools in that family, it’s really just a formatted reader of data from /proc — mainly /proc/meminfo, /proc/stat, and /proc/vmstat.

Checking the version on my system:

vmstat --version
vmstat from procps-ng 4.0.4

Running it with no arguments gives a single summary snapshot:

vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st gu
 0  0      0 3830708  11696 132364    0    0  4844     1  304    5 10 38 51  1  0  0

That’s a lot packed into two lines. Let’s take it apart column by column, because understanding this table is the entire point of learning vmstat.

Understanding Every Column

procs (Process Statistics)

  • r — number of processes currently runnable, i.e., waiting for CPU time (in the run queue, not necessarily blocked). If this number is consistently higher than your CPU core count, you have CPU contention.
  • b — number of processes in uninterruptible sleep, usually waiting on I/O. A persistently high b value is one of the strongest signals of a disk I/O bottleneck.

memory (in KB by default)

  • swpd — amount of virtual memory currently swapped out to disk.
  • free — amount of idle memory, completely unused.
  • buff — memory used as buffers (raw disk blocks).
  • cache — memory used as page cache (file contents cached from disk).

A common beginner mistake is panicking over a low free value. On a healthy Linux system, the kernel deliberately uses “unused” RAM for cache, because cache can be reclaimed instantly. What matters more is whether swpd is climbing.

swap

  • si — amount of memory swapped in from disk, per second.
  • so — amount of memory swapped out to disk, per second.

Any sustained non-zero values here are a red flag. Swapping means the kernel had to move memory pages to disk because physical RAM was under pressure, and disk is orders of magnitude slower than RAM. If si/so are consistently active, the system needs more RAM, or something is consuming more than it should.

io

  • bi — blocks received from a block device (reads), in blocks/second.
  • bo — blocks sent to a block device (writes), in blocks/second.

These give you a rough sense of disk activity without needing iostat.

system

  • in — interrupts per second, including the clock.
  • cs — context switches per second.

A sudden spike in cs can indicate a process (or many processes) thrashing between CPU and waiting states — common with lock contention or a runaway scheduler situation.

cpu (percentages)

  • us — time spent running user-space (non-kernel) code.
  • sy — time spent running kernel code (system calls, interrupts).
  • id — idle time.
  • wa — time spent waiting on I/O. This is often the single most diagnostic number on the whole line — high wa with low us/sy means the CPU is sitting there waiting for disk, not actually computing anything.
  • st — “stolen” time, relevant in virtualized environments — time the hypervisor gave to other VMs instead of yours.
  • gu — guest time, time spent running a virtual CPU for a guest OS (shown on some kernel versions with virtualization support).

On my sandbox environment (a VM), the extra gu column shows up because of the virtualized CPU:

us sy id wa st gu
10 38 51  1  0  0

Full Syntax and Options

vmstat [options] [delay [count]]

The real power of vmstat is in the delay and count arguments:

vmstat 2 5

This prints a new line every 2 seconds, 5 times total. This is how you actually watch trends instead of a single frozen snapshot — I almost never run plain vmstat on a real investigation; I run it with a delay.

Key flags, pulled straight from vmstat --help on my system:

Options:
 -a, --active           active/inactive memory
 -f, --forks            number of forks since boot
 -m, --slabs            slabinfo
 -n, --one-header       do not redisplay header
 -s, --stats            event counter statistics
 -d, --disk             disk statistics
 -D, --disk-sum         summarize disk statistics
 -p, --partition <dev>  partition specific statistics
 -S, --unit <char>      define display unit
 -w, --wide             wide output
 -t, --timestamp        show timestamp
 -y, --no-first         skips first line of output

-a: Active/Inactive Memory

vmstat -a

Replaces the buff/cache columns with inact (inactive) and active memory — useful when you want to see how much cached memory the kernel considers reclaimable versus actively in use.

-s: Full Statistics Dump

This is one of my favorites for a full picture in one shot:

vmstat -s
      4093928 K total memory
       313728 K used memory
        76908 K active memory
        75032 K inactive memory
      3830456 K free memory
        11696 K buffer memory
       132364 K swap cache
            0 K total swap
            0 K used swap
            0 K free swap
          189 non-nice user cpu ticks
            0 nice user cpu ticks
          698 system cpu ticks
          962 idle cpu ticks
           18 IO-wait cpu ticks
            0 IRQ cpu ticks
            4 softirq cpu ticks
            0 stolen cpu ticks
            0 non-nice guest cpu ticks
            0 nice guest cpu ticks

This is essentially a cumulative counter view rather than a rate — useful for a “since boot” summary.

-d: Disk Statistics

vmstat -d

Shows per-disk reads, writes, I/O time, and merges — a lighter-weight alternative to iostat when you just need a quick check and don’t have sysstat installed.

-m: Slab Info

vmstat -m

Shows kernel slab allocator statistics — how much memory the kernel itself is using for internal object caches (inodes, dentries, network buffers, etc.). This one’s more of a kernel-internals diagnostic than a typical sysadmin daily-driver, but it matters when you suspect kernel memory (not user-space memory) is what’s growing unbounded.

-S: Unit Conversion

vmstat -S M

Displays memory figures in megabytes instead of kilobytes. Valid units: k (1000), K (1024, default), m (1,000,000), M (1,048,576).

-t: Timestamps

vmstat -t 2 5

Adds a timestamp column to each line — essential if you’re logging vmstat output to a file for later analysis, since otherwise you can’t correlate a spike with wall-clock time.

How vmstat Works Internally

vmstat doesn’t maintain its own state or talk to the kernel through special system calls. On Linux, it reads directly from:

  • /proc/meminfo — memory figures
  • /proc/stat — CPU ticks, interrupts, context switches, forks
  • /proc/vmstat — detailed virtual memory event counters
  • /proc/diskstats — for the -d disk statistics mode

For rate-based columns (si, so, bi, bo, in, cs), vmstat calculates the delta between two reads of the underlying counters, divided by the elapsed time — which is exactly why the very first line of vmstat‘s output (when run without a delay, or the first line of a delayed run) represents averages since boot, not a live rate. Every subsequent line in a delayed run is a genuine live rate over that interval. This trips people up constantly: if you only run vmstat once, you’re seeing a boot-to-now average, not “right now.” Always use a delay and look at the second line onward for real-time data.

Real-World Use Cases

Quick health check during an incident:

vmstat 1 10

Watch the r, wa, and si/so columns for ten seconds. If r is way above your core count and wa is climbing, you likely have I/O-bound contention, not CPU-bound.

Logging for later analysis:

vmstat -t 5 720 > /var/log/vmstat_$(date +%F).log &

This logs a timestamped sample every 5 seconds for an hour (720 samples), backgrounded — a common pattern I use before a load test or deployment window so I have hard data if something goes wrong.

Detecting memory pressure in a monitoring script:

#!/bin/bash
SWAP_IN=$(vmstat 1 2 | tail -1 | awk '{print $7}')
if [ "$SWAP_IN" -gt 0 ]; then
    echo "ALERT: active swapping detected (si=$SWAP_IN)" | logger -t vmstat-check
fi

Diagnosing a “slow but idle-looking” server: if top shows low CPU usage but users report slowness, vmstat 1 5 with a consistently non-zero wa column usually points straight at disk I/O as the real bottleneck — a network storage mount timing out, a failing disk, or a backup job hammering I/O in the background.

vmstat vs Related Commands

ToolBest ForWeakness
vmstatFast overall system snapshot: CPU, memory, swap, I/O in one lineNo per-process breakdown
top / htopPer-process CPU/memory ranking, interactiveBusier display, harder to log cleanly
iostatDeep per-device disk I/O statisticsRequires sysstat package, not always installed by default
freeMemory-only snapshot, easier to read for just RAM/swapNo CPU or I/O context
sarHistorical, logged system performance data (needs sysstat)Requires setup/cron beforehand; not useful retroactively without it

My personal rule of thumb: vmstat first for the “what’s generally going on” question, then top/htop if it looks CPU or process related, then iostat if it looks disk related.

Performance Optimization Notes

  • If si/so are consistently non-zero, adding RAM or reducing memory-hungry processes is the real fix — swap is a symptom, not the disease.
  • If wa is consistently high, check disk health (smartctl), consider faster storage (SSD/NVMe), or investigate what’s generating so much I/O (iotop can identify the specific process).
  • A consistently high cs (context switches) relative to your workload can point to lock contention in an application, or too many threads competing for too few cores.

Security Implications

vmstat itself is a read-only reporting tool and doesn’t modify system state, so it carries essentially no direct security risk. The one thing worth noting: its output can reveal system load patterns and memory pressure to any local user (it doesn’t require root), which in shared/multi-tenant systems could theoretically be used for reconnaissance in a side-channel sense — though this is a minor and largely theoretical concern compared to more direct information leaks elsewhere on the system.

Compatibility Across Distributions

vmstat is part of procps / procps-ng, which ships by default on essentially every mainstream Linux distribution — Debian, Ubuntu, RHEL, CentOS, Fedora, Arch, openSUSE. Minor differences exist between very old procps versions and the newer procps-ng fork (which most distros migrated to years ago), mainly in extra columns like gu (guest time) and some flag names, but the core column layout has been stable for decades.

Reading a Real Diagnostic Session Start to Finish

It helps to walk through how these pieces fit together during an actual investigation rather than treating each column as an isolated fact. Say a report comes in that an application feels sluggish. The first move is vmstat 1 10, watching ten seconds of live samples rather than a single snapshot. If the r column sits comfortably below core count, CPU scheduling contention is probably not the story. If wa is elevated and the b column shows processes stuck in uninterruptible sleep, the next move is confirming disk involvement with iostat -x 1 (if available) or checking vmstat -d for per-device read/write counts. If instead si/so are both non-zero and climbing, the story shifts to memory pressure, and the next step becomes identifying which process is consuming the most RSS memory rather than chasing disk I/O at all. This kind of layered elimination — ruling categories out with vmstat before reaching for a heavier, more specific tool — is the actual skill worth building, more so than memorizing any single column in isolation.

Summary

vmstat earns its place as one of the first tools I reach for during any performance investigation because it condenses process, memory, swap, I/O, and CPU activity into one readable line, refreshed at whatever interval I choose. It’s not a replacement for deeper tools like iostat or per-process profilers, but as a fast, dependency-light “what’s actually going on right now” check, it’s hard to beat — and understanding its columns makes every other monitoring tool on Linux easier to read too.

References

  • man 8 vmstat
  • procps-ng project: https://gitlab.com/procps-ng/procps
  • Linux kernel documentation: Documentation/filesystems/proc.rst
  • man 5 proc
Total
0
Shares

Leave a Reply

Previous Post
uptime command in Linux and it perimeters

uptime Command in Linux: Complete Guide to System Uptime and Load Average Parameters

Next Post
how to see system information via the /proc file system

How to See System Information via the /proc File System: Complete Linux System Monitoring Guide

Related Posts