I/O wait (often written iowait or shown as wa or %iowait) is the percentage of time a CPU is idle while at least one task is blocked waiting for disk I/O or other block I/O to complete. Among server resources it is a key indicator that storage, rather than processing power, is limiting work, and on Linux servers it appears in tools such as top, vmstat, iostat and sar.
The metric is easy to misread. I/O wait is a form of idle time, not busy time: the CPU could run other work if any were ready. A high value says that runnable work is stuck behind storage, but it does not by itself measure how slow the disks are or how much I/O is happening.
How the kernel accounts for I/O wait
The Linux kernel samples each CPU at every timer tick and assigns the interval to a category such as user, system, idle or steal. When a CPU has nothing runnable but a task that last ran on it is in uninterruptible sleep waiting for block I/O, the tick is counted as iowait instead of idle.
This accounting has two important consequences. First, iowait only exists when the CPU is otherwise idle; if a busy process occupies the core, the same storage stall is invisible in the metric. Second, on multi-core systems the value is averaged across cores, so one blocked thread on a 32-core server can show as roughly 3 percent while a single application is completely stalled.
The following table shows where iowait sits among the standard CPU time categories.
| Category | Field in top | Meaning |
|---|---|---|
| User | us | Running application code |
| System | sy | Running kernel code |
| Idle | id | Nothing to do |
| I/O wait | wa | Idle while block I/O is pending |
| Steal | st | Virtual CPU waiting for the hypervisor |
| Interrupts | hi and si | Hardware and software interrupt handling |
Interpreting I/O wait values
There is no universal threshold for healthy I/O wait, because the value depends on core count, workload and how much other CPU work exists. The ranges below are practical starting points for a general-purpose server, not fixed rules.
| Sustained I/O wait | Typical interpretation | Next step |
|---|---|---|
| Below 5 percent | Storage is rarely the limit | No action needed |
| 5 to 20 percent | Noticeable storage dependence | Check latency with iostat |
| 20 to 40 percent | Storage likely limits throughput | Find the processes doing I/O |
| Above 40 percent | Severe storage bottleneck | Investigate disk, RAID or network storage |
The decisive companion metrics are device latency and utilization. In iostat -x, the r_await and w_await columns show average request time in milliseconds, and %util shows how busy the device is. A healthy NVMe drive typically answers in well under 1 ms, a SATA SSD in about 1 ms or less, and a spinning disk in 5 to 15 ms; values far above these, together with high iowait, confirm the diagnosis.
I/O wait compared with related resource metrics
I/O wait is frequently confused with load average, disk I/O and CPU steal time, yet each answers a different question. Reading them together prevents wrong conclusions.
| Metric | What it measures | How it relates to I/O wait |
|---|---|---|
| Load average | Runnable plus uninterruptible tasks | Rises with I/O stalls on Linux |
| Disk I/O | Operations and bytes per second | Shows volume, not waiting |
| CPU steal time | Time taken by the hypervisor | Also idle-like, but for CPU access |
| CPU utilization | Share of time doing work | Excludes iowait in most tools |
| Swap activity | Pages moved to and from disk | A common hidden cause of iowait |
On Linux, tasks in uninterruptible sleep (state D) count toward load average, so a server with high load but low CPU usage is often waiting on storage. Swap is a frequent root cause: when memory usage exceeds RAM, page faults turn into disk reads and iowait climbs even though the application itself does little explicit I/O.
Diagnosing and reducing high I/O wait
Diagnosis proceeds from confirming the storage problem to identifying the responsible process and finally choosing a fix. A typical sequence uses vmstat 1 for the overall trend, iostat -x 1 for per-device latency, and iotop or pidstat -d to see which processes read and write the most.
| Symptom | Likely cause | Typical fix |
|---|---|---|
| High iowait with swap activity | Memory pressure | Add RAM or reduce memory usage |
| High iowait during backups | Bulk reads compete with production | Schedule or throttle backups |
| High write latency | Many small synchronous writes | Batch writes or tune fsync behavior |
| One saturated device | Hot data on a single disk | Spread data or move to SSD or NVMe |
| High latency on network storage | Congested SAN or NFS path | Check network and array load |
Faster media usually brings the largest and quickest improvement, but caching often matters as much: a database that fits its working set in memory reads from RAM instead of disk. Capacity planning should therefore track iowait together with memory headroom, not in isolation.
Pitfalls when reading I/O wait
Several well-known measurement pitfalls make iowait unreliable as a single source of truth.
- Low iowait does not prove fast storage, because a CPU-busy server hides storage stalls in user or system time.
- Averages across cores dilute stalls, so per-CPU views such as
mpstat -P ALLare more revealing. - Inside virtual machines the value is approximate, since the guest cannot see host-level queuing.
- Network file systems contribute to iowait, so the bottleneck may be the network rather than a local disk.
- Short spikes are normal during log rotation, backups or cache flushes; sustained values matter more.
Explained without jargon
Imagine a chef who is ready to cook but has to stand and wait for ingredients from the storeroom. I/O wait measures that kind of waiting. The processor is not tired or overloaded. It simply has nothing to do until the data arrives from storage.
A little waiting is normal. When the waiting becomes a large share of the time, the storage is the slow part, and a faster processor would not help. The fix is to speed up the storeroom, or to keep more ingredients close at hand in memory.
A typical use case
A small hosting company runs a virtual server with 8 vCPUs and 16 GB of RAM for an online shop. Customers complain that pages load slowly every night between 1:00 and 2:00. During that window top shows only 15 percent user CPU but 45 percent iowait, and the load average climbs above 12.
The administrator runs iostat -x 1 and sees write latency on the data volume jump from about 2 ms to over 80 ms. iotop reveals that a full database dump and a file-level backup start at the same time and saturate the disk. The team moves the file backup to a separate window and throttles the dump. Night-time iowait drops below 10 percent, and page response times return to normal without any hardware upgrade.