High iowait can make a system feel slow even when the CPUs are mostly idle, because runnable work stalls behind disk or storage operations. Spotting elevated I/O wait helps separate storage-related slowdowns from CPU-bound load when commands hang, requests time out, or queue depths grow.
Linux accounts CPU time into states such as user, system, idle, and I/O wait, and exposes those counters in /proc/stat. Tools like vmstat and top read the same kernel counters and present them as the wa percentage for the sampling interval.
Short spikes in wa are common during bursts of writes, log rotation, or cache flushes, while sustained wa often points to slow or saturated storage, overloaded virtual disks, or delayed network-mounted filesystems. Treat iowait as a symptom rather than a root cause, and sample during the period of slowness for a meaningful signal.
Steps to check CPU I/O wait with vmstat and top in Linux:
- Sample iowait with vmstat over a short interval.
$ vmstat 1 5 procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu------- r b swpd free buff cache si so bi bo in cs us sy id wa st gu 1 0 0 2983936 31072 797068 0 0 1593 2717 359 2 3 1 96 0 0 0 0 0 0 2986348 31072 797164 0 0 0 0 38 46 0 0 100 0 0 0 0 0 0 2986348 31072 797164 0 0 0 0 33 44 0 0 100 0 0 0 0 0 0 2989204 31072 797164 0 0 0 0 26 36 0 0 100 0 0 0 0 0 0 2991704 31072 797164 0 0 0 0 34 44 0 0 100 0 0 0
The first data line is an average since boot; focus on later lines for current wa. A rising b column alongside high wa often indicates tasks blocked on I/O.
- Capture the wa value from top in batch mode.
$ top -b -n 1 | head -n 5 top - 12:15:47 up 6 min, 2 users, load average: 0.38, 0.15, 0.06 Tasks: 122 total, 1 running, 120 sleeping, 0 stopped, 1 zombie %Cpu(s): 0.0 us, 4.3 sy, 0.0 ni, 95.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st MiB Mem : 3901.5 total, 2923.3 free, 326.9 used, 809.0 buff/cache MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 3574.6 avail Mem
The %Cpu(s) line shows aggregated CPU state; wa is time spent waiting on I/O while the CPU has nothing runnable.
- Collect a longer vmstat sample during the slow period to confirm sustained I/O wait.
$ vmstat 5 3 procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu------- r b swpd free buff cache si so bi bo in cs us sy id wa st gu 1 0 0 2993660 31080 797312 0 0 1576 2687 356 2 3 1 96 0 0 0 1 0 0 2997828 31088 797312 0 0 0 5 30 39 0 0 100 0 0 0 0 0 0 3004672 31088 797460 0 0 40 72 51 85 0 0 100 0 0 0
Consistently elevated wa across many samples indicates persistent waiting rather than a transient spike.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
