Fixing High Load Average on Linux When CPU Usage Looks Normal
Load average is climbing but top shows plenty of idle CPU. This almost always means processes stuck waiting on I/O, not a CPU problem — here's how to actually find which one.
Linux’s load average counts processes that are either running or waiting to run — including processes blocked waiting on I/O, not just ones actually consuming CPU. A high load average alongside low CPU usage almost always means the second case: something is stuck waiting on disk, network, or another slow resource.
Step 1: confirm this is actually an I/O-wait situation
top
Check the %wa (I/O wait) figure in top’s CPU summary line — a high load average combined with a high %wa and low %us/%sy confirms processes are waiting on I/O rather than genuinely needing more CPU.
Step 2: find processes in uninterruptible sleep
ps aux | awk '$8 ~ /D/ {print}'
Process state D (uninterruptible sleep) specifically means a process is blocked on a kernel-level I/O operation it cannot be interrupted out of — these are exactly the processes inflating load average without touching the CPU.
Step 3: identify what those processes are actually waiting on
cat /proc/<pid>/stack
cat /proc/<pid>/status | grep State
Reading a blocked process’s kernel stack (where permitted) often shows exactly which kernel function it’s stuck in — frequently something disk-I/O-related (wait_on_page_bit, a filesystem journal commit) or network-filesystem-related (an NFS call, similar to FreeBSD’s NFS hard-mount hangs).
Step 4: check overall disk I/O activity system-wide
iostat -x 1
High %util on a specific block device, combined with elevated await (average wait time per I/O request), points at that device being the actual bottleneck — distinguishing “the disk is just slow/overloaded” from “one specific runaway process is issuing excessive I/O.”
Step 5: identify which process is generating the most I/O
iotop
iotop shows per-process disk I/O in something close to real time, which is often the fastest way to identify a single runaway process (a backup job, a misbehaving database query, log rotation gone wrong) responsible for saturating disk I/O for everything else.
Step 6: check for swap thrashing as a distinct cause
vmstat 1
free -h
Heavy swap activity (high si/so columns in vmstat) produces a similar symptom — high load, low CPU usage — but with a different root cause and different fix (more RAM, or reducing memory pressure, rather than addressing disk I/O directly).
Step 7: check for a specific slow storage backend
mount | grep nfs
df -h
If the implicated processes are all touching a network-mounted filesystem specifically, the bottleneck may be the remote storage or the network path to it, not local disk hardware at all.
Why “high load, low CPU” is a specific, well-defined signature worth recognizing immediately
This particular combination is one of the most reliable diagnostic signals Linux offers — it points away from CPU-bound causes (which would show high %us) and directly toward I/O as the bottleneck, letting you skip straight to iostat/iotop rather than wasting time investigating CPU-bound explanations that the load-average-vs-CPU-usage mismatch has already ruled out.