iostat - CPU and Disk I/O Statistics Cheatsheet
iostat reports CPU utilization and per-device disk I/O statistics — throughput, IOPS, request latency, and queue depth. It is the standard first stop for diagnosing storage bottlenecks on Linux: is the disk saturated, are requests queuing, is latency spiking? It ships as part of the sysstat package alongside mpstat, pidstat, and sar.
Installation
| Platform | Command |
|---|
| Debian/Ubuntu | sudo apt install sysstat |
| Fedora/RHEL | sudo dnf install sysstat |
| Arch Linux | sudo pacman -S sysstat |
| macOS | iostat is built in (different output) |
| Verify | iostat -V |
Basic Usage
| Command | Description |
|---|
iostat | One report since boot (CPU + devices) |
iostat 2 | Refresh every 2 seconds |
iostat 2 5 | 5 reports, 2 seconds apart |
iostat -x | Extended stats (the useful ones) |
iostat -d | Device stats only (no CPU) |
iostat -c | CPU stats only |
The Command You Actually Want
# Extended, human-readable, per-device, every 2s
iostat -xmt 2
| Flag | Effect |
|---|
-x | Extended statistics (util%, await, aqu-sz, …) |
-m | Report in MB/s (use -k for KB/s) |
-t | Print a timestamp with each report |
-p DEV | Show partitions of a device (e.g. -p sda) |
-d 2 | Device report every 2 seconds |
-h | Human-readable, NVMe-friendly formatting |
Reading Extended Output (-x)
| Column | Meaning |
|---|
r/s, w/s | Read/write requests per second (IOPS) |
rMB/s, wMB/s | Read/write throughput |
rareq-sz / wareq-sz | Average request size |
r_await, w_await | Avg read/write latency (ms) — key metric |
aqu-sz | Average queue depth (requests in flight) |
%util | Fraction of time the device was busy |
Interpreting the Signals
| Observation | Interpretation |
|---|
%util near 100% | Device is saturated (careful on SSD/NVMe — can parallelize) |
High await (tens of ms+) | Requests are slow — latency bottleneck |
High aqu-sz | Requests piling up faster than the disk drains |
| High IOPS, low throughput | Small random I/O (typical DB/metadata workload) |
| Low IOPS, high throughput | Large sequential I/O (backups, streaming) |
On modern SSD/NVMe, %util can read 100% while the device still has headroom (it services requests in parallel). Trust await and aqu-sz more than %util there.
CPU Section
| Field | Meaning |
|---|
%user / %nice | Time in user space |
%system | Time in the kernel |
%iowait | CPU idle waiting on I/O (storage pressure hint) |
%steal | Time stolen by the hypervisor (noisy neighbors) |
%idle | Idle time |
High %iowait alongside high disk await points squarely at storage as the bottleneck.
Common Workflows
# Watch a suspected disk bottleneck live
iostat -xmt 2
# Focus on one device and its partitions
iostat -xmt -p nvme0n1 2
# Correlate CPU iowait with device latency during a load test
iostat -xmt 1 60 > iostat.log
| Tool | Focus |
|---|
| iostat | Per-device I/O + CPU stats |
| iotop | Which process is doing the I/O |
| dstat/dool | Combined CPU/disk/net in one view |
| sar | Historical/recorded system activity |
Use iostat to see the device is slow, then iotop to find which process is responsible.
Resources