Lesson 10 of 19 · Level 2 — Intermediate: troubleshooting
Performance triage
When a server is 'slow', find out why in minutes. The USE method (utilisation, saturation, errors) applied to CPU, memory, disk and network, with the classic 60-second checklist of commands.
Don't guess. Check every resource the same way.
"The server is slow" could be CPU, memory, disk, network, or a lock inside the application. The USE method (Brendan Gregg) gives you a checklist. For every resource, check:
- Utilisation: how busy is it?
- Saturation: is work queuing for it?
- Errors: is it failing?
A supermarket feels slow. Is every till busy (utilisation)? Is there a long queue at the tills (saturation)? Is a till broken (errors)? You check the tills, then the trolleys, then the car park, the same three questions each time, until you find the bottleneck.
| Resource | Utilisation | Saturation | Errors |
|---|---|---|---|
| CPU | mpstat, top (%us, %sy) |
vmstat r > number of CPUs; load average |
rare |
| Memory | free -h (available) |
swap activity (vmstat si/so), OOM kills |
dmesg OOM messages |
| Disk | iostat -x %util |
iostat aqu-sz, await |
dmesg I/O errors |
| Network | sar -n DEV throughput vs link speed |
drops, retransmits (sar -n ETCP, ss -ti) |
ip -s link errors |
The 60-second checklist
$ uptime
10:42:11 up 12 days, 3:04, 2 users, load average: 7.92, 6.10, 3.40
Load averages over 1, 5 and 15 minutes. Compare them with the number of CPUs (nproc). Rising (1-min > 15-min) means it's getting worse now.
$ 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
9 0 0 181212 90312 5213440 0 0 2 40 3121 5902 88 10 2 0 0
8 0 0 180980 90312 5213460 0 0 0 52 3050 5811 89 9 2 0 0
- r (runnable) 8–9 on a 4-CPU box → CPU saturated.
- us 88% → user code is burning CPU (find it with
pidstat 1). - wa would show time waiting for I/O; si/so non-zero → swapping (memory pressure).
$ pidstat 1 1
UID PID %usr %system %CPU CPU Command
1001 3321 350.00 8.00 358.00 2 java
One Java process using ~3.6 CPUs. Now it's an application question (a hot loop, garbage collection, traffic spike), and you have the evidence.
Disk:
$ iostat -xz 1 2
Device r/s w/s rkB/s wkB/s r_await w_await aqu-sz %util
nvme0n1 3.0 910.0 12.0 58240.0 0.40 38.20 34.80 99.60
%util near 100%, a queue (aqu-sz) of 35, and writes taking 38 ms (w_await): the disk is the bottleneck.
Memory:
$ free -h
total used free shared buff/cache available
Mem: 7.7Gi 1.3Gi 180Mi 12Mi 6.2Gi 6.1Gi
Swap: 0B 0B 0B
Only 180 MiB "free", but 6.1 GiB available. Linux fills spare RAM with cache and gives it back on demand. Worry when available is low, when swap is active, or when dmesg shows OOM kills.
History: what happened at 3 a.m.?
sar (from sysstat, with its collector enabled) records all of the above every 10 minutes by default:
$ sar -u -f /var/log/sysstat/sa27 -s 02:30:00 -e 03:30:00 # CPU on the 27th, 02:30–03:30
$ sar -r # memory history today
(The data path is /var/log/sa/ on the RHEL family.)
Try it: create load, then find it
Install sysstat and stress-ng on a VM, then for each scenario open a second terminal and run the checklist. Name the bottleneck before looking at what you started.
- CPU:
stress-ng --cpu $(nproc) --timeout 120s - Memory:
stress-ng --vm 2 --vm-bytes 90% --timeout 120s. Watchfree -h,vmstatsi/so anddmesg. - Disk:
stress-ng --hdd 2 --timeout 120s. Watchiostat -xz 1and thewacolumn. - Write one line per scenario: utilisation / saturation / errors for the resource that was the bottleneck.
Going deeper: beyond the checklist
- Steal time (
stin vmstat/top) on VMs means the hypervisor gives your CPU time to someone else. A noisy neighbour, not your code. - CPU throttling in containers looks like slowness with idle CPUs: check cgroup
cpu.stat(nr_throttled) orcontainer_cpu_cfs_throttled_*metrics (see Kubernetes Administration, lesson 23). - Latency, not averages: the average can look fine while the p99 is terrible. Tools like
biolatencyandrunqlat(lesson 16, eBPF) show distributions. - Always record before and after numbers for any tuning change. Tuning without measurement is superstition.
Recap
- USE: utilisation, saturation, errors, for CPU, memory, disk and network.
- Checklist:
uptime,dmesg,vmstat,mpstat,pidstat,iostat -x,free -h,sar -n DEV,top. - High load + idle CPU → I/O wait; low "free" but high "available" → healthy cache.
saranswers "what happened earlier?";dmesgcatches OOM kills and hardware errors.
This site is a public version of my personal engineering knowledge hub. It intentionally excludes confidential company information and internal operational details.