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:

  1. 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.

  2. 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.

  3. 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.