Skip to content
Français
Account: not signed in, sync available My learning
Select theme
Français

Check the system load on Linux with uptime and vmstat

By updated

Improve this page

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 uptime and /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, top and /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.

Terminal window
uptime
08:13:36 up 14 days, 22:25, 4 users, load average: 0,50, 0,53, 0,41

The 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.

Terminal window
cat /proc/loadavg
0.50 0.53 0.41 1/2509 2953827
ValueMeaning
0.501-minute load average
0.535-minute load average
0.4115-minute load average
1/25091 process currently running out of 2509 existing
2953827Last 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:

Terminal window
nproc
16
Load averageCoresRatioInterpretation
0.50160.03Very lightly loaded system
8.00160.50Moderate load (50%)
16.00161.00All cores busy, critical threshold
32.00162.00Queue 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.

PatternMeaning
1min > 5min > 15minThe load is rising, something just started
1min < 5min < 15minThe load is falling, the peak is over
The 3 values closeStable load for 15 minutes
1min very high, 15min normalOne-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.

Terminal window
vmstat 1 5
procs -----------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
ColumnMeaningWhat to look at
rRunning processes (run queue)If r > nproc → CPU saturated
bProcesses blocked on I/OIf b > 0 regularly → disk problem
us% user CPUApplication work
sy% system CPUKernel work
id% idle CPUFree time
wa% CPU waiting for I/OThe key signal: high wa = disk bottleneck
si/soSwap in / Swap outIf > 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.

Terminal window
top -bn1 | head -5
top - 08:13:38 up 14 days, 22:26, 4 users, load average: 0,50, 0,53, 0,41
Tasks: 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 st
MiB Mem : 47953,2 total, 6890,4 free, 16420,6 used, 25271,6 buff/cache
MiB Swap: 4096,0 total, 3830,2 free, 265,8 used. 31532,6 avail Mem

The %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.

Terminal window
# By CPU
ps aux --sort=-%cpu | head -10
# By memory
ps aux --sort=-%mem | head -10

In 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.

Terminal window
free -h
total used free shared buff/cache available
Mem: 46Gi 16Gi 6,6Gi 33Mi 24Gi 30Gi
Swap: 4,0Gi 265Mi 3,7Gi
ValueWhat to look at
availableMemory really usable (includes reclaimable cache)
Swap usedIf > 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:

Terminal window
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:

Terminal window
cat /proc/pressure/cpu
some avg10=0.00 avg60=0.04 avg300=0.01 total=16325330830
full avg10=0.00 avg60=0.00 avg300=0.00 total=0
Terminal window
cat /proc/pressure/memory
some avg10=0.00 avg60=0.00 avg300=0.00 total=3943556
full avg10=0.00 avg60=0.00 avg300=0.00 total=3814571
Terminal window
cat /proc/pressure/io
some avg10=0.04 avg60=0.23 avg300=0.09 total=1144701447
full avg10=0.03 avg60=0.21 avg300=0.09 total=1058047928
Filesomefull
cpuAt least one process waits for CPUPresent since kernel 5.13, but stays close to 0 by design
memoryAt least one process waits for memoryAll processes wait
ioAt least one process waits for an I/OAll 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.

  1. Overall load

    Terminal window
    uptime
    nproc

    Compute the load/nproc ratio. If > 1, continue the diagnosis.

  2. CPU or I/O?

    Terminal window
    vmstat 1 5

    Look at wa (I/O wait) and r (run queue). If wa > 20% → disk problem. If r > nproc → CPU saturated.

  3. Memory

    Terminal window
    free -h

    If available is very low or Swap used is high → not enough memory.

  4. Identify the culprit

    Terminal window
    ps aux --sort=-%cpu | head -5
    ps aux --sort=-%mem | head -5
  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 cores
LOAD=$(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)"
fi

The 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.

SymptomProbable causeSolution
High load, high CPU idleProcesses blocked on disk I/Ovmstat: check wa and b, move to SSD
High load, low wa, high usReal CPU loadIdentify the process with top (P key)
Swap permanently in useNot enough RAMAdd RAM or reduce the number of services
OOM killer in dmesgMemory exhausted, processes killedIncrease RAM, configure cgroup limits
Load at 0 but slow serverNetwork or application problemCheck ss -tulpn, network latencies
Load rises in regular peaksScheduled cron or batchcrontab -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 nproc to interpret it
  • Three values (1, 5, 15 min) give the trend: rising, stable or falling
  • wa in vmstat is the key signal to tell CPU overload from disk I/O overload
  • free -h: look at available, not free, 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

6 questions
6 min
70% to pass

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

Is this project useful to you?

The guides, courses, quizzes and labs stay free. If you use them regularly, you can contribute to their upkeep and development.

Become a supporting member (new tab) One-time support (new tab) Learn more

Follow the project on LinkedIn