Understanding Linux Load Average
Load average measures scheduler demand—not CPU usage. Learn what the three numbers really mean, how to interpret them per CPU count, and how to separate CPU from I/O load.
Before you start
- ▸Root or sudo access to the target system
- ▸sysstat package installed for sar and iostat (apt install sysstat / dnf install sysstat / pacman -S sysstat)
- ▸Basic familiarity with reading terminal output from top or htop
The three numbers printed by uptime, top, and htop are some of the most misread figures in Linux administration. Load average does not measure CPU utilisation—it measures demand on the scheduler. Getting that distinction right changes how you diagnose slow systems entirely.
What Load Average Actually Measures
Linux load average is an exponentially decaying moving average of the number of threads that are either running (actively using a CPU) or runnable (ready to run, waiting for a CPU) or in uninterruptible sleep (waiting on I/O, kernel locks, or certain syscalls). The three values cover the past 1, 5, and 15 minutes.
The uninterruptible sleep part is what makes Linux load average uniquely different from, say, BSD or macOS. A disk bottleneck with zero CPU pressure can push load sky-high on Linux. This was a deliberate 1993 kernel patch, and it remains controversial, but it means load is really a measure of system demand, not just CPU demand.
Formally, the kernel updates load every 5 seconds using:
# The raw load values are exposed here (values are fixed-point, divide by 2^16)
cat /proc/loadavg
Typical output looks like 1.42 0.95 0.73 2/412 18932. The first three fields are the 1-, 5-, and 15-minute averages. The fourth field shows running/total threads; the fifth is the most recent PID.
The Run Queue and How It Relates to CPUs
Each logical CPU (hardware thread) can run exactly one thread at a time. The run queue holds every thread waiting its turn. A load average of 1.0 on a single-core machine means the CPU is just barely keeping up—one thread is always either running or waiting. A load of 2.0 means there is, on average, one extra thread queued behind the active one.
On a multi-core or multi-threaded system, the break-even load equals the number of logical CPUs. Find that number first:
nproc
# or for a fuller picture:
lscpu | grep -E '^CPU\(s\)|^Thread|^Core|^Socket'
A load average equal to your CPU count means every logical CPU is busy but nothing is queued. Above that, threads are waiting. Below it, the system has headroom. A load of 8.0 on a 16-core machine is comfortable; the same load on a 2-core machine is a crisis.
A Simple Rule of Thumb
- Load / nproc < 0.7 — healthy, plenty of headroom
- Load / nproc ≈ 1.0 — fully utilised, investigate trend
- Load / nproc > 1.0 — demand exceeds capacity, threads are queuing
- Load / nproc > 5.0 — serious saturation, likely causing latency problems
Always look at all three averages together. A spike in 1-minute load with low 15-minute load is probably a burst, not a structural problem. Rising 15-minute load that has not levelled off is a trend worth acting on immediately.
CPU Load vs I/O Load: Telling Them Apart
Because uninterruptible sleep counts toward load, a database server hammering slow disks can show a load of 30 while top shows CPU idle at 90%. Distinguishing the source is the essential diagnostic step.
Check CPU utilisation first:
top -b -n 1 | head -5
Look at the %id (idle) column in the Cpu(s) line. High idle + high load = I/O or lock contention, not a CPU problem.
Confirm with vmstat, which shows the run queue (r) and blocked-on-I/O (b) columns directly:
# Sample every 2 seconds, 5 times
vmstat 2 5
The r column is runnable threads; b is threads in uninterruptible sleep. If b dominates, your load is I/O-driven.
For deeper I/O analysis:
# Install if missing: apt install sysstat / dnf install sysstat / pacman -S sysstat
iostat -x 2 5
Look at %util per device and await (average I/O wait time in milliseconds). A device at 100% util with high await is your bottleneck.
Reading Load in Context: Practical Tools
uptime and w
uptime
# Output example: 14:32:11 up 12 days, 3:14, 2 users, load average: 2.41, 1.87, 1.52
w
w also shows which users are logged in and their active commands—useful for spotting an admin running a runaway job.
top and htop
top
# Press 1 to expand per-CPU usage
# Press f, then select fields to add nTH (threads) view
In htop, enable the Load Average meter in the setup screen (F2). The per-CPU bars let you see whether load is spread evenly or pinned to specific cores, which points to single-threaded bottlenecks.
sar for historical load
sar from the sysstat package records system statistics to /var/log/sa/ (Debian/Ubuntu: /var/log/sysstat/) when enabled. Once running, you can query historical load:
# Enable sysstat collection (run once)
# Debian/Ubuntu:
sudo systemctl enable --now sysstat
# Fedora/RHEL/Rocky:
sudo systemctl enable --now sysstat
# Arch: sysstat is in community; same systemd unit name
# View load average for today
sar -q
# View a specific date (file from /var/log/sa/)
sar -q -f /var/log/sa/sa15
The ldavg-1, ldavg-5, and ldavg-15 columns match uptime output. The runq-sz column shows the actual run queue depth at each sample interval, which is more precise than the averaged load figure.
Investigating High Load: A Step-by-Step Approach
- Check
uptime. Note whether load is rising, stable, or falling across the three windows. - Run
vmstat 1 10and compare therandbcolumns to determine CPU vs I/O origin. - If CPU-bound: use
topsorted by CPU (Pkey) to find the offending process. Checkpidstat -u 1 10for per-process CPU detail. - If I/O-bound: use
iostat -x 1 10to identify the saturated device. Follow up withiotop -aoto find which processes are doing the I/O. - Check for kernel-level contributors:
cat /proc/loadavgcombined withps aux | awk '$8 ~ /D/'lists processes currently in uninterruptible sleep (state D).
# List all processes currently in uninterruptible sleep
ps aux | awk 'NR==1 || $8 ~ /^D/'
# Real-time I/O attribution (requires iotop)
sudo iotop -ao
Verification
After making a change (tuning I/O scheduler, adding capacity, fixing a runaway process), watch the 1-, 5-, and 15-minute averages converge downward. Because the 15-minute average is slow to respond, allow at least 20 minutes of stable operation before concluding the fix held. Use sar -q 1 60 to capture a clean minute of run-queue data as a baseline.
Troubleshooting Common Misreadings
- High load, CPU idle, no obvious I/O — look for kernel lock contention. NFS hangs, faulty storage drivers, and memory pressure causing swap thrashing all show up as D-state processes inflating load without obvious disk I/O in
iostat. - Load drops to near zero but system still feels slow — check memory pressure with
free -handvmstat'ssi/so(swap-in/swap-out) columns. Swap thrashing can stall processes without maintaining a high run queue. - Transient spikes at the same time each minute — almost always a cron job. Check
journalctl -u cronorjournalctl -u crondand correlate timestamps withsar -q. - Very high load on container hosts — load average on the host reflects all containers. A single misbehaving container can inflate the host load without being obvious from inside other containers. Always investigate at the host level with
systemd-cgtopordocker stats.
Frequently asked questions
- Is a load average of 1.0 always bad?
- No. On a 16-core machine, a load of 1.0 means the system is nearly idle. Load is only meaningful relative to the number of logical CPUs. Divide load by `nproc` to get a utilisation ratio.
- Why can load average be high when CPU usage is low?
- Linux counts threads in uninterruptible sleep (D state) toward load average. Processes blocked on slow disks, NFS mounts, or certain kernel locks inflate load without consuming CPU cycles.
- Which load average value should I alert on?
- Monitor the 5-minute average for operational alerting—it smooths out short bursts without lagging as much as the 15-minute average. Alert when load / nproc consistently exceeds 1.0 over a 5-minute window.
- Does load average account for CPU frequency scaling or hyperthreading?
- No. The kernel counts logical CPUs regardless of their clock speed or whether they are hyperthreaded. Two hyperthreads share execution resources, so effective saturation often occurs at lower raw load figures on heavily threaded workloads.
- How do containers and VMs affect load average readings?
- A VM's load average reflects only the vCPUs it can see, but the host scheduler may be contended. On container hosts, load is reported system-wide and includes all containers; use `systemd-cgtop` or cgroup-aware tools to attribute load per container.
Related guides
AI and Artificial-Life Tools on Linux
Set up open-source AI/ML and artificial-life toolkits on Linux: PyTorch, JAX, DEAP, Avida, NetLogo, and RL environments with GPU driver guidance.
Assembly Language on Linux: A Starter Guide
Write x86-64 assembly on Linux from scratch: install NASM and GAS, learn syscalls, assemble and link a working program, then inspect and debug it.
How to Benchmark Disk Performance with fio
Learn to benchmark Linux disk performance with fio: writing job files, testing latency and throughput, and interpreting IOPS and percentile output correctly.
The Linux Boot Process Explained
Trace the full Linux boot sequence from UEFI firmware through GRUB2, the kernel, initramfs, and systemd to your login prompt — with diagnostics at each stage.