Skip to content
daniel@cosenza:~/blog
LinuxFix March 14, 2026 2 min read

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.