Happy Dussehra! May good always win. Happy Diwali! Wishing you a bright year ahead. Merry Christmas! Warm wishes from Vizag. Happy New Year! Here’s to a great year ahead.

Archive · Linux

Performance Triage: Load, CPU, Memory and Disk

A repeatable five-minute method for finding which resource is the bottleneck, using vmstat, iostat, sar and pidstat, plus how to read the numbers.

4 min read

  • Ubuntu 18.04.3 LTS
  • sysstat 11.6
  • procps-ng 3.3.12
  • iostat
  • pidstat

“The server is slow” is a symptom, not a diagnosis. Triage means finding which resource is saturated in a few minutes, before touching anything. This post gives a fixed order of checks and explains how to read each number.

Versions in use on this date. sysstat 11.6.1 (iostat, mpstat, pidstat, sar) and procps-ng 3.3.12 on Ubuntu 18.04.3 LTS. Install sysstat with sudo apt install sysstat, then set ENABLED="true" in /etc/default/sysstat so sar keeps history.

The method

flowchart TB
  S[Slow server reported] --> U[uptime<br/>load averages]
  U --> V[vmstat 1<br/>run queue swap io wait]
  V --> C{What dominates?}
  C -->|high us or sy| CPU[CPU - mpstat and pidstat -u<br/>find hot process]
  C -->|high wa or D state| IO[Disk - iostat -x<br/>find busy device and process]
  C -->|si so non zero or low avail| MEM[Memory - free and ps by RSS<br/>OOM kills in dmesg]
  C -->|all quiet| NET[Network and app<br/>ss and application logs]
  CPU --> FIX[Decide - tune, scale or fix code]
  IO --> FIX
  MEM --> FIX
  NET --> FIX

Use the USE method: for each resource ask about Utilisation, Saturation and Errors.

1. Load average

uptime
nproc

Load is the average number of tasks running or waiting (including waiting for disk) over 1, 5 and 15 minutes. Compare to the core count: load 8 on 8 cores is full; load 8 on 2 cores means a queue. A rising 1-minute value versus the 15-minute shows whether it is getting worse.

2. vmstat

vmstat 1 5
Column Reading
r Runnable tasks; sustained above core count means CPU saturation
b Tasks blocked on I/O
si / so Swap in and out; any steady non-zero value means memory pressure
wa CPU time waiting for I/O
us / sy / id / st User, kernel, idle, steal from hypervisor

3. CPU

mpstat -P ALL 1 3                 # per-core usage; one core at 100% = single-threaded bottleneck
pidstat -u 1 5                    # CPU per process over time
top -o %CPU                       # (or: top, then P)

High sy points to the kernel (many system calls, network handling, context switches); high st on a VM means the host is oversubscribed, which only the provider can fix.

4. Memory

free -m
ps -eo pid,user,rss,cmd --sort=-rss | head
vmstat -s | head -12
dmesg -T | grep -i -E 'out of memory|killed process'

Read available, not free: Linux fills spare RAM with cache that is released on demand. Concern starts when available is low and swap is in use or the OOM killer fired.

5. Disk

iostat -xz 1 3
pidstat -d 1 5                    # per-process read and write rates
df -h; df -i
sudo lsof +L1 | head
iostat column Reading
%util Near 100% means the device is saturated (misleading on SSD/NVMe, check latency too)
await Average ms per request; milliseconds on SSD, tens of ms on spinning disk is normal, hundreds is not
aqu-sz Queue depth
r/s, w/s, rkB/s Throughput

Cloud disks have IOPS and throughput limits; a burst-credit volume that runs out of credits looks exactly like a sudden disk bottleneck.

6. Network and application

sar -n DEV 1 3                    # interface throughput
ss -s                             # socket summary, look for huge TIME-WAIT counts
ss -tn state established | wc -l
sudo tail -n 100 /var/log/syslog

If the host looks idle yet the application is slow, the problem is probably inside it: slow database queries, lock waits, an external API, DNS delays or thread pool limits. Check application logs and timings next.

Look back in time with sar

sar -u -s 09:00:00 -e 11:00:00        # CPU history
sar -r                                # memory history
sar -q                                # load and run queue history
sar -d -p                             # disk history

History answers “what happened at 3 AM” when nobody was watching.

Write it down

Record what you saw (numbers, timestamps) and the single change you made, one at a time. Add the bottleneck to your monitoring as an alert, so next time you hear about it before the user does.