iostat Explained
vmstat tells you there’s I/O happening somewhere on the system. iostat tells you exactly which disk, how busy it is, and how long requests are taking to complete. It’s the standard tool for confirming whether a specific storage device is a performance bottleneck.
Installing iostat
iostat ships as part of the sysstat package, which most distributions don’t install by default.
# Debian/Ubuntu
sudo apt install sysstat
# Fedora/RHEL
sudo dnf install sysstat
# Arch
sudo pacman -S sysstat
Basic Usage
iostat -xz 1
-x: extended statistics (the useful columns, covered below)-z: omit devices with zero activity during the interval, keeping output readable1: repeat every 1 second
Example output:
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz %util
sda 4.00 82.00 64.00 4128.00 0.00 6.00 0.00 6.82 0.50 2.13 0.18 9.40
nvme0n1 0.00 310.00 0.00 39680.00 0.00 0.00 0.00 0.00 0.00 0.31 0.10 12.60
Key Columns
| Column | Meaning |
|---|---|
r/s, w/s | Reads and writes completed per second |
rkB/s, wkB/s | Kilobytes read and written per second |
rrqm/s, wrqm/s | Read/write requests merged per second by the kernel’s I/O scheduler |
r_await, w_await | Average time in milliseconds for reads/writes to complete, including queue wait |
aqu-sz | Average queue size, the number of requests waiting plus in flight |
%util | Percentage of time the device had at least one request outstanding |
Reading %util Correctly
On traditional spinning disks, %util approaching 100% is a reliable signal the device is saturated and can’t accept work any faster. On modern NVMe SSDs, this metric is less reliable in isolation: NVMe drives handle many parallel requests through deep internal queues, so a device can show high %util while still having plenty of capacity left, since even a single outstanding request keeps the device “busy” by this metric’s definition. For NVMe, aqu-sz and await are more trustworthy indicators of actual saturation.
await: The Metric That Matters Most
await (shown as r_await/w_await in extended mode on modern versions) is the average time a request took to complete, from submission to completion, including any time spent waiting in queue. This reflects real, felt latency better than throughput numbers do. A disk can show modest throughput but terrible await if it’s fielding many small, random requests rather than large sequential ones.
As a rough guide: await values in the low single-digit milliseconds are typical for a healthy SSD under light load. Values climbing into the tens or hundreds of milliseconds, especially paired with a growing aqu-sz, indicate the device is struggling to keep up with demand.
Watching a Specific Device
iostat -x /dev/nvme0n1 1
On systems with many disks, the full table can be wide and noisy. Passing a specific device name narrows output to just that disk, useful once you already suspect where the bottleneck is.
Typical Triage Flow
A common diagnostic sequence: notice high wa (I/O wait) in vmstat or top, then run iostat -xz 1 to see which specific device has elevated await and aqu-sz, then use iotop (a separate tool, requires root) to identify which process is generating that I/O load.
# see which process is driving disk I/O (needs root)
sudo iotop -o
Frequently Asked Questions
What does iostat show that vmstat does not?
vmstat reports aggregate I/O activity across the whole system as a single bi/bo number. iostat breaks I/O statistics down per block device, showing throughput, request counts, average request size, queue depth, and utilization for each disk separately. On a system with multiple disks, this is the only way to identify which specific device is the bottleneck.
How do I install iostat on Linux?
iostat is part of the sysstat package, which is not installed by default on most distributions. On Debian and Ubuntu, install it with sudo apt install sysstat. On Fedora and RHEL-based systems, use sudo dnf install sysstat. Once installed, the iostat command is immediately available with no further configuration needed for basic usage.
What does percent util mean in iostat output?
percent util is the percentage of time the device had at least one I/O request outstanding, effectively how busy the device was during the sampling interval. On traditional spinning disks, values approaching 100 percent indicate the device is saturated. On modern NVMe SSDs with deep internal queues, 100 percent util can still leave headroom, since a single outstanding request keeps the metric high even when the device could handle many more in parallel.
What is await in iostat and why does it matter?
await is the average time, in milliseconds, that I/O requests took to complete, including time spent waiting in the queue plus actual service time. It is one of the most useful iostat metrics because it reflects real, felt latency. Rising await values, especially alongside a growing queue length, are a reliable early signal of a disk becoming a bottleneck before other metrics show obvious problems.
How do I run iostat with extended statistics?
Use iostat -x to enable extended statistics, which adds columns like await, svctm (on older versions), percent util, and average queue size that are not shown in the default output. Most real diagnostic work uses iostat -x 1 to sample extended stats every second, since the default summary-only output rarely has enough detail to diagnose a specific problem.
How do I check disk I/O for just one specific device?
Pass the device name as an argument, for example iostat -x /dev/sda 1 to watch only /dev/sda with extended stats every second. This is useful on systems with many disks where the full output is too wide or noisy to read easily, letting you focus on the device you already suspect is the problem.