| Tested on | RHEL 10.2 (Coughlan) — vm1.lab.example (3 logical CPUs) |
|---|---|
| Package | procps-ng 4.0.4-11.el10sysstat 12.7.6-4.el10util-linux 2.40.2-18.el10 |
| Applies to | Ubuntu, Debian, Kali Linux, Linux Mint, Pop!_OS, Raspberry Pi OS, elementary OS, Zorin OS, Parrot OS, MX Linux, RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Arch Linux |
| Privilege | Normal user for uptime, top, ps, mpstat, and iostat; sudo or root for pidstat per-process I/O and some sysstat options |
| Scope | Diagnose Linux high load average and high load with low CPU using load averages, CPU counts, mpstat, iowait, D state processes, vmstat, iostat, and pidstat. Does not cover application profiling, cgroup limits, or full disk I/O monitoring reference. |
| Related guides | Monitor disk I/O performance Check memory usage per process Linux process management Processors, cores, and threads stress command |
uptime prints load average: 8.42, 6.11, 4.03 while top shows ninety percent idle — that combination confuses teams who treat load as “CPU percent.” On Linux, load counts how many tasks want the CPU or sit in uninterruptible sleep, averaged over one, five, and fifteen minutes.
The workflow below compares load to your CPU count, splits user, system, and I/O wait time, hunts D state blockers, and ties the signals together so you know whether to fix CPU, disk, or something waiting on the kernel.
What Linux load average actually measures
Load average is not CPU utilization. It is a moving average of runnable and uninterruptible tasks — processes ready to run plus processes stuck in D state waiting on kernel I/O.
Read the three numbers from uptime or /proc/loadavg:
uptime09:22:27 up 1:01, 5 users, load average: 0.25, 0.17, 0.27The values are the one-, five-, and fifteen-minute averages. A single spike in the first number with lower long-term values often means a brief burst already fading. All three numbers climbing together means sustained pressure.
The same figures appear in top and in /proc/loadavg when scripts poll the host:
cat /proc/loadavg0.25 0.17 0.27 1/754 21271The fourth field (1/754 here) is runnable tasks over total tasks — useful when you graph load alongside process counts.
Compare load with available CPUs
Load only makes sense next to how many CPUs the kernel can schedule. Count logical processors:
nproc3On this lab VM, load averages around 0.25 mean far fewer than three tasks are competing for CPU time — a healthy idle host. Rule of thumb: sustained load above nproc means the run queue or uninterruptible sleep backlog is larger than the CPU can drain quickly.
Cross-check with lscpu when you need thread and socket detail for sizing:
lscpu | grep -E '^CPU\(s\)|^Model name'CPU(s): 3
Model name: Intel(R) Core(TM) Ultra 5 135UHyper-threading and guest vCPUs both count toward nproc. A 16-thread laptop can tolerate higher load numbers than a 2-vCPU VM before users feel lag.
Check CPU utilization
Once you know load and CPU count, split where time goes — user, system, idle, and I/O wait. mpstat from the sysstat package prints per-interval CPU breakdown:
mpstat -P ALL 1 2On an idle host, %idle stays high and %iowait stays near zero:
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 2.73 0.00 3.07 0.00 3.24 0.51 0.00 0.00 0.00 90.44On the lab host I started CPU stress in one session:
stress --cpu 3 --timeout 8While stress runs, sample again with mpstat in another terminal — user and system time climb while idle drops:
mpstat -P ALL 1 2Average: all 50.00 0.00 29.41 0.00 14.71 2.94 0.00 0.00 0.00 2.94High %usr with load near nproc usually means CPU-bound work — find the top consumers:
pidstat -u 1 2Sort by CPU in top when you need a live view — the first summary line repeats load and CPU states:
top -b -n 1 | head -5top - 09:22:38 up 1:01, 7 users, load average: 0.36, 0.19, 0.28
Tasks: 282 total, 1 running, 281 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 91.4 id, 0.0 wa, 5.7 hi, 2.9 si, 0.0 stThe %Cpu(s) line labels match mpstat: us user, sy system, id idle, wa I/O wait. When load is high but us and sy stay low, look at I/O wait and D state next — not more CPU cores.
Check I/O wait
%iowait is the share of CPU time spent idle while at least one task waits on disk I/O. It explains “slow server” reports when load is elevated but user CPU looks fine.
Poll with mpstat and watch the %iowait column:
mpstat 1 3Average: all 1.27 0.00 4.98 1.16 6.94 1.04 0.00 0.00 0.00 84.61Sustained %iowait above roughly ten to twenty percent on a busy server — context matters — often means disks or the storage path are the bottleneck. Pair it with iostat in the disk section below.
vmstat puts runnable and blocked counts beside I/O wait in one row:
vmstat 1 3procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
r b swpd free buff cache si so bi bo in cs us sy id wa st gu
1 0 0 2103876 5052 3396940 0 0 844 249 900 4 2 7 91 0 0 0r is runnable tasks, b is blocked in uninterruptible sleep, and wa is I/O wait percentage — the same story as mpstat in a compact snapshot.
Find processes in D state
Processes in D (uninterruptible sleep) wait on kernel I/O and count toward load even when they use no CPU time. List them:
ps -eo stat,pid,comm | awk '$1 ~ /D/'No output on a healthy idle lab host means nothing is stuck in D right now — that is the result you want during normal operation.
When output appears, the STAT column shows D and the command name points at the blocked workload — often dd, database writers, or NFS clients. Those processes cannot be killed with SIGKILL until the kernel completes the I/O or times out the mount.
Count blocked tasks quickly:
ps -eo state | grep -c '^D'0A non-zero count with rising load and low %usr is a strong signal to inspect disks or NFS, not to add CPU.
Diagnose high load with low CPU
“High load, low CPU” is a common search phrase because load and CPU utilization measure different things. Load includes:
- Runnable tasks waiting for CPU time
- Tasks in
Dstate blocked on I/O - Short bursts that average into the one-minute figure
When top shows high idle and load still exceeds nproc, check three places in order:
vmstat— risingb(blocked) with moderatermpstat— rising%iowaiteven when%usris lowps— processes inDstate
On the lab host, stress --io 4 raised the one-minute load without maxing user CPU:
uptime09:23:37 up 1:02, 5 users, load average: 0.95, 0.36, 0.330.95 on three CPUs is a modest queue — on production hardware, the same pattern at 12 on four CPUs with %iowait at thirty percent points at storage, not a need for faster application code. Confirm memory pressure separately if vmstat shows swap in (si/so); see check memory usage per process when free and swap traffic look wrong.
Check disk, NFS, and other blocking I/O
When %iowait or D state implicates I/O, identify which device is saturated. iostat reports per-disk utilization and queue depth:
iostat -xz 1 2avg-cpu: %user %nice %system %iowait %steal %idle
2.27 0.00 6.57 0.30 0.00 90.85
Device r/s w/s rkB/s wkB/s w_await aqu-sz %util
sda 33.81 6.33 818.56 139.70 6.46 0.09 2.13Focus on %util near one hundred percent and w_await / r_await in milliseconds — disks that stay fully utilized with high await times back up the whole system and inflate load.
Per-process disk reads and writes use pidstat:
pidstat -d 1 2When the heavy consumers are NFS clients, check mounted NFS paths and server health:
mount | grep nfsStale or hung NFS mounts often leave processes in D until the server responds — soft versus hard mount options change whether tasks fail or wait indefinitely. For deeper disk tuning, see monitor disk I/O performance and how to improve disk I/O performance.
Identify the actual bottleneck
Match the dominant signal to the fix — chasing CPU when disks are saturated wastes effort.
| What you see | Likely bottleneck | Next step |
|---|---|---|
Load ≈ nproc, high %usr, low %iowait |
CPU-bound | pidstat -u, top; scale out or optimize hot processes |
Load > nproc, high %iowait, high disk %util |
Disk I/O | iostat -xz; spread data, faster storage, reduce sync writes |
High load, low %usr, many D processes |
Blocking I/O (disk, NFS, FC) | ps for D; check mounts, array latency, multipath |
High %sys, moderate load |
Kernel or lock contention | pidstat -w for context switches; audit drivers, antivirus, tracing |
High r in vmstat, load > CPUs, low I/O wait |
CPU run queue | More CPU capacity or fewer runnable threads |
Rising si/so in vmstat with sluggish apps |
Memory pressure | Check memory usage per process; add RAM or reduce footprint |
Re-check uptime after each change — the one-minute average should fall within a few minutes if you removed the real blocker:
uptime09:23:22 up 1:02, 6 users, load average: 0.55, 0.26, 0.30Load dropped after stress exited, which is the pattern you want after killing a runaway job or fixing a stuck mount.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
Load high, CPU idle, %iowait high |
Slow or saturated disk | iostat; balance LVM, RAID, or move hot data; check SMART errors |
Load high, many D processes, NFS mounts |
Hung NFS server or network | Remount with correct options; fix server; avoid hard without timeouts on non-critical paths |
Load high, %usr high on few PIDs |
Runaway user process | kill or renice; fix application bug or cron overlap |
| Load spiked once, now normal | Short batch or backup | Correlate with cron; schedule I/O-heavy jobs off peak |
| Load high after kernel update | Driver or firmware regression | Check dmesg; roll back or patch storage driver |
b column high in vmstat, no obvious disk util |
Block layer or multipath wait | multipath -ll; storage vendor tools; check FC/iSCSI paths |
References
- proc(5) — Linux manual page (
/proc/loadavg) - mpstat(1) — Linux manual page
- iostat(1) — Linux manual page
- vmstat(8) — Linux manual page
- ps(1) — Linux manual page
Summary
High load average on Linux means runnable or uninterruptible tasks are backing up — not automatically that CPUs are at one hundred percent. Compare the three load figures from uptime to nproc first; sustained load above the CPU count deserves investigation.
mpstat and top split user, system, idle, and I/O wait time. High %usr with load near the CPU count is CPU-bound work; high load with low user CPU and rising %iowait or vmstat b points at disk or NFS blocking. ps for D state finds tasks stuck in the kernel that still inflate load.
iostat names saturated disks through %util and await times; pidstat ties I/O to processes. Use the bottleneck table to pick whether you need more CPU, faster storage, a fixed mount, or memory — not all four at once. For recurring disk pressure, continue with monitor disk I/O performance; for runaway processes, see Linux process management.

