The load average measures the average number of processes waiting to run or waiting for I/O over 1, 5 and 15 minutes. To interpret it, divide it by the number of CPU cores (nproc): a ratio above 1.0 means the system is overloaded. This guide is written for the administrator facing a slow server who must quickly decide between three culprits: the CPU, the memory or the disks. It chains uptime, vmstat, top, free and /proc/pressure into a five-step diagnostic method, then a script alert. The commands come from the procps package, present on any server installation but missing from minimal container images, such as Debian 13's.
What you will learn
- Read the load average with
uptimeand/proc/loadavg - Interpret the 3 values against the number of CPU cores
- Tell apart CPU overload, I/O overload and memory saturation
- Diagnose in real time with
vmstat,topand/proc/pressure - Identify the processes responsible for the overload
- Set up a simple alert in a script
In what context?
Checking the system load comes up in many situations:
- A web server responds slowly, and you must quickly determine whether it is a CPU, memory or disk problem
- After a deployment, you check that the application does not saturate the resources
- A monitoring alert reports a high load average, and you must qualify the nature of the problem
- You are preparing a sizing: how many cores and how much RAM are really used?
- In an interview or an exam, you are asked to diagnose a slow server: the system load is the first reflex
The load average with uptime
Read the load at a glance
uptime answers in one line: how long the machine has been up, how many users are logged in, and the three load averages.
uptime 08:13:36 up 14 days, 22:25, 4 users, load average: 0,50, 0,53, 0,41The three values are the average load over 1 minute, 5 minutes and 15 minutes. The commas in this output come from a French locale; with an English locale, uptime prints 0.50, 0.53, 0.41.
Read from /proc/loadavg
uptime actually reformats a file the kernel keeps up to date permanently: /proc/loadavg. Reading it directly is useful in a script, because the last two columns that uptime hides give extra information, notably the number of currently runnable processes. The first value remains the 1-minute load average, exactly as in uptime.
cat /proc/loadavg0.50 0.53 0.41 1/2509 2953827| Value | Meaning |
|---|---|
0.50 | 1-minute load average |
0.53 | 5-minute load average |
0.41 | 15-minute load average |
1/2509 | 1 process currently running out of 2509 existing |
2953827 | Last PID assigned |
Interpret the load average
The load average is the average number of processes that are either running (CPU) or in uninterruptible wait (D state), that is almost always a disk I/O or an NFS share. An ordinary network wait does not count: a process blocked on a TCP connection stays in the S state, measured on Debian 13. To interpret it, compare it with the number of cores:
nproc16| Load average | Cores | Ratio | Interpretation |
|---|---|---|---|
| 0.50 | 16 | 0.03 | Very lightly loaded system |
| 8.00 | 16 | 0.50 | Moderate load (50%) |
| 16.00 | 16 | 1.00 | All cores busy, critical threshold |
| 32.00 | 16 | 2.00 | Queue building up, processes slowed down |
Trend: what the gap between the 3 values reveals
A single load value says nothing about the direction. The strength of the three measurements (1, 5 and 15 minutes) is to show whether the load is rising or falling: just compare their order of magnitude. Read them from left to right, from the most recent to the oldest. This reflex avoids a classic mistake on call: panicking over a high 1-minute load while the 5- and 15-minute values show a peak already falling back.
| Pattern | Meaning |
|---|---|
| 1min > 5min > 15min | The load is rising, something just started |
| 1min < 5min < 15min | The load is falling, the peak is over |
| The 3 values close | Stable load for 15 minutes |
| 1min very high, 15min normal | One-off peak, probably a batch or a deployment |
CPU load or I/O load?
A high load average does not necessarily mean the CPU is overloaded. Processes waiting for disk I/O count too. Two tools let you tell them apart.
With vmstat
vmstat prints one line per interval: here five measurements one second apart. Ignore the first line, which averages everything since boot, and read the following ones.
vmstat 1 5procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu------- r b swpd free buff cache si so bi bo in cs us sy id wa st gu 0 0 272128 7061744 4444732 21433220 0 1 61 561 15162 23 4 2 94 0 0 0 0 0 272128 7061384 4444732 21433280 0 0 0 0 2274 3284 1 1 99 0 0 0 0 0 272128 7055740 4444732 21433296 0 0 0 136 2615 17379 1 1 98 0 0 0| Column | Meaning | What to look at |
|---|---|---|
r | Running processes (run queue) | If r > nproc → CPU saturated |
b | Processes blocked on I/O | If b > 0 regularly → disk problem |
us | % user CPU | Application work |
sy | % system CPU | Kernel work |
id | % idle CPU | Free time |
wa | % CPU waiting for I/O | The key signal: high wa = disk bottleneck |
si/so | Swap in / Swap out | If > 0 → not enough memory |
With top
top in batch mode (-b) with a single iteration (-n1) gives a snapshot you can paste into a ticket. Its first five lines summarise the whole machine.
top -bn1 | head -5top - 08:13:38 up 14 days, 22:26, 4 users, load average: 0,50, 0,53, 0,41Tasks: 472 total, 1 running, 471 sleeping, 0 stopped, 0 zombie%Cpu(s): 1,1 us, 1,1 sy, 0,0 ni, 97,7 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 stMiB Mem : 47953,2 total, 6890,4 free, 16420,6 used, 25271,6 buff/cacheMiB Swap: 4096,0 total, 3830,2 free, 265,8 used. 31532,6 avail MemThe %Cpu(s) line gives the breakdown at a glance: high id = quiet system, high wa = I/O problem.
Identify the greedy processes
Once the saturated resource is known, ps sorted on the right column names the process responsible.
# By CPUps aux --sort=-%cpu | head -10
# By memoryps aux --sort=-%mem | head -10In top, press P to sort by CPU or M to sort by memory.
Check memory and swap
free -h shows memory in readable units. The available column matters more than free, for a reason detailed right below.
free -h total used free shared buff/cache availableMem: 46Gi 16Gi 6,6Gi 33Mi 24Gi 30GiSwap: 4,0Gi 265Mi 3,7Gi| Value | What to look at |
|---|---|
available | Memory really usable (includes reclaimable cache) |
Swap used | If > 0, the system ran short of RAM at some point |
Check whether the OOM killer stepped in
When memory runs out, the kernel's OOM killer (Out Of Memory) kills processes to survive, and says so in the kernel log:
sudo dmesg | grep -i "out of memory"If lines appear, the system had to kill processes for lack of memory: it is a critical signal.
PSI, Pressure Stall Information (recent kernels)
On Linux kernels 4.20+, /proc/pressure/ gives a precise indicator of the pressure on each resource:
cat /proc/pressure/cpusome avg10=0.00 avg60=0.04 avg300=0.01 total=16325330830full avg10=0.00 avg60=0.00 avg300=0.00 total=0cat /proc/pressure/memorysome avg10=0.00 avg60=0.00 avg300=0.00 total=3943556full avg10=0.00 avg60=0.00 avg300=0.00 total=3814571cat /proc/pressure/iosome avg10=0.04 avg60=0.23 avg300=0.09 total=1144701447full avg10=0.03 avg60=0.21 avg300=0.09 total=1058047928| File | some | full |
|---|---|---|
cpu | At least one process waits for CPU | Present since kernel 5.13, but stays close to 0 by design |
memory | At least one process waits for memory | All processes wait |
io | At least one process waits for an I/O | All processes wait |
The full line of the cpu file does exist on recent kernels, as the example above shows with total=0. It stays almost zero: a process ready to run always ends up getting CPU, so the notion of total blocking makes little sense there. On memory and io, however, a non-negligible full means that the whole system is stalled waiting for the resource, the most serious signal.
The avg10, avg60, avg300 values are the averages over 10, 60 and 300 seconds (as a % of time). As a rule of thumb, not an official threshold, a value that stays above 5% deserves investigation.
Quick diagnosis, the method
The five steps below go from the overall view to the culprit. Each one decides whether the next is needed: a load/nproc ratio below 1 often ends the investigation at step one.
-
Overall load
Terminal window uptimenprocCompute the load/nproc ratio. If > 1, continue the diagnosis.
-
CPU or I/O?
Terminal window vmstat 1 5Look at
wa(I/O wait) andr(run queue). Ifwa > 20%→ disk problem. Ifr > nproc→ CPU saturated. -
Memory
Terminal window free -hIf
availableis very low orSwap usedis high → not enough memory. -
Identify the culprit
Terminal window ps aux --sort=-%cpu | head -5ps aux --sort=-%mem | head -5 -
Check the history
Terminal window sudo dmesg | grep -i "out of memory"journalctl --since "1 hour ago" -p err
Simple alert in a script
An automatic check only needs two numbers, the 1-minute load and the number of cores, and a decimal comparison. Bash can only compare integers: the version below hands the comparison to awk, available everywhere, rather than to bc, missing from a minimal Debian 13.
#!/bin/bash# Alert if the load exceeds the number of coresLOAD=$(awk '{print $1}' /proc/loadavg)CPUS=$(nproc)
if awk -v l="$LOAD" -v c="$CPUS" 'BEGIN { exit !(l > c) }'; then logger -p user.warning "ALERT: load $LOAD exceeds $CPUS cores on $(hostname)"fiThe alert goes to the system journal with logger, where your monitoring picks it up: journalctl -p warning --since today shows it. Sending an email (mail) assumes a mail server configured on the machine, which is rarely the case. Schedule this script with a systemd timer or cron every 5 minutes.
Troubleshooting
This table links each observable symptom to its most probable cause. Read the middle column first: the first two lines show the same apparent symptom, a high load, but point to opposite causes, the disk in one case, the CPU in the other. The line not to miss is the last but one, load at 0 but slow server: it reminds you that the load average completely ignores network and application latency.
| Symptom | Probable cause | Solution |
|---|---|---|
| High load, high CPU idle | Processes blocked on disk I/O | vmstat: check wa and b, move to SSD |
| High load, low wa, high us | Real CPU load | Identify the process with top (P key) |
| Swap permanently in use | Not enough RAM | Add RAM or reduce the number of services |
| OOM killer in dmesg | Memory exhausted, processes killed | Increase RAM, configure cgroup limits |
| Load at 0 but slow server | Network or application problem | Check ss -tulpn, network latencies |
| Load rises in regular peaks | Scheduled cron or batch | crontab -l, systemctl list-timers to identify |
Key points
- The load average = average number of processes running or in uninterruptible wait (disk I/O, NFS); divide it by
nprocto interpret it - Three values (1, 5, 15 min) give the trend: rising, stable or falling
wain vmstat is the key signal to tell CPU overload from disk I/O overloadfree -h: look atavailable, notfree, to assess the remaining memory margin- PSI (
/proc/pressure/) gives the real pressure on CPU, memory and I/O on recent kernels - A load > nproc is not always a CPU problem: always check wa and swap before concluding
- In production, set up automated monitoring (Prometheus/Grafana) rather than manual checks
Knowledge check
Check that the essentials of this guide are acquired. The questions only cover what has just been explained here.
Knowledge check
Check what you have learned with this interactive quiz
How it works
- The timer starts when you click Start
- Multiple choice, true/false and short answer questions
- You can move between questions
- Detailed results are shown at the end
Starts the quiz and the timer
Review
(0/0)Score by domain
A domain groups several guides and gets several questions, so its score is more reliable than a per-topic score, which often rests on a single question.
Summary
Strengths
No topic passed at 80% on at least two questions yet.
Weak areas
No topic below the pass mark.
Recommended next
Hints before you try again?
Continue the course: Check disk space and inodes on Linux
A new full quiz with random questions
Work again only on the questions you missed