Linux

The first five minutes on a slow server

Eight commands, in the order to run them, that show whether a slow server is short of CPU, memory, or disk, or whether the problem is somewhere else, before you change anything.

Written againstDebian 12Ubuntu 24.04RHEL 9procps-ng 4sysstat 12
Reading time
5 min
Commands to copy
11
Last checked
24 Oct 2026

Before restarting anything, spend five minutes finding out which resource is short. The commands below each take a few seconds, and each one narrows down what the next should look at. The order follows Brendan Gregg’s 60-second checklist from Netflix, shortened to what a single server needs. The example output comes from different machines, each showing the problem that command is best at finding.

Four of them come from sysstat, which isn’t installed by default. Install it before you need it: sudo apt install sysstat on Debian and Ubuntu, sudo dnf install sysstat on RHEL.

1. Load average with uptime

shell
$ uptime 14:02:11 up 41 days,  3:17,  2 users,  load average: 11.84, 9.02, 4.10$ nproc4

The three numbers are the load averaged over 1, 5 and 15 minutes. Compare them with the CPU count: 11.84 on four CPUs means about three times more work is waiting than the machine can run, and the 1-minute value above the 15-minute one means it’s getting worse. On Linux the load also counts processes waiting for the disk, so a high load can also mean a busy disk. The next commands tell the two apart.

2. Kernel messages with dmesg

shell
$ sudo dmesg -T | tail -20[Sat Oct 24 13:58:40 2026] Out of memory: Killed process 30112 (java) total-vm:6123456kB, anon-rss:4890112kB[Sat Oct 24 13:59:02 2026] I/O error, dev sdb, sector 81920 op 0x1:(WRITE) flags 0x0 phys_seg 1 prio class 2

Look for the OOM killer, disk and filesystem errors, and network links going up and down. Any of these explains a slow server on its own, and none of the later commands would show it as clearly.

3. CPU, memory, and waits with vmstat

shell
$ 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 2  9 1572864  81240  10212 412880  612  904  9812  1204 2210 4120  6  4 22 68  0 1 11 1574912  79112  10212 409744  588 1012 10240   988 2301 4388  5  5 19 71  0

The first line is the average since boot. Read the ones after it. In this example the CPUs are mostly idle (us + sy is about 10%), but 9 to 11 processes are blocked (b), the CPUs spend 70% of their time waiting for disk (wa), and pages move to and from swap every second (si, so). That’s a machine out of memory, swapping, and slowed down by its own disk.

ColumnWhat it tells you
rProcesses ready to run. Above the CPU count for long means CPU saturation.
bProcesses blocked, usually waiting for the disk.
si, soMemory swapped in and out per second. Anything above 0 for long means too little memory.
us, syCPU time in programs and in the kernel.
waCPU time spent idle while waiting for disk.
stSteal: time the hypervisor gave to other virtual machines. Above a few percent, the host is overbooked.

4. Each CPU with mpstat

shell
$ mpstat -P ALL 1 1# %guest and %gnice left out, and only the first two CPUs shownAverage:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %idleAverage:     all   26.50    0.00    1.75    0.25    0.00    0.50    0.00  71.00Average:       0   99.00    0.00    1.00    0.00    0.00    0.00    0.00   0.00Average:       1    3.00    0.00    2.00    1.00    0.00    1.00    0.00  93.00

One CPU at 100% while the others are idle means a single-threaded process is the limit. Adding cores won’t help; the process has to do less or work in parallel. If every CPU is busy, find the process next.

5. Busy processes with pidstat

shell
$ pidstat 1 3Average:      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  CommandAverage:     1001     30544   94.33    2.00    0.00    0.67   96.33     -  javaAverage:      999      2210    3.00    2.00    0.00    1.00    5.00     -  postgres

Like top, but it prints a line per interval instead of redrawing the screen, so you can copy it into a ticket. pidstat -d 1 shows disk reads and writes per process instead of CPU.

6. Disk latency with iostat

shell
$ iostat -xz 1 3# columns trimmed to the ones that matter hereDevice      r/s     rkB/s  r_await    w/s    wkB/s  w_await  aqu-sz  %utilsda       812.00  10240.00    38.12  64.00   988.00    51.40   33.10  99.60

r_await and w_await are how long a read or write takes in milliseconds, queueing included. On an SSD they’re usually below 1. aqu-sz is how many requests are waiting. %util near 100 says the device is busy all the time, though an SSD or a RAID set can serve more than one request at once and still have room at 100%. Long waits are the reliable sign.

7. Available memory with free

shell
$ free -h               total        used        free      shared  buff/cache   availableMem:           7.8Gi       7.3Gi        79Mi        12Mi       404Mi       230MiSwap:          2.0Gi       1.5Gi       512Mi

Read available, not free. Linux uses spare memory as a disk cache and gives it back when programs need it, so a low free on its own is normal. 230 MB available out of 7.8 GB, with 1.5 GB in swap, isn’t. To see which processes hold the memory:

shell
$ ps aux --sort=-rss | head -5

8. Network traffic with sar and ss

shell
$ sar -n DEV 1 3Average:        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutilAverage:         eth0    412.00    388.00     61.20    502.90      0.00      0.00      0.00      0.41$ ss -s

Compare the throughput with the link speed: 503 kB/s is about 4 Mbit/s, 0.4% of a 1 Gbit/s link. ss -s counts connections by state. Thousands in timewait or a growing number of established connections point at a client or a backend that doesn’t let go.

What the numbers point to

You seeIt points toLook next at
Load above the CPU count, us + sy highCPUpidstat and top for the process, then the process itself
One CPU at 100%, the others idleA single-threaded processWhat that process is doing
b above 0, wa high, long r_await or w_awaitThe diskpidstat -d 1 for the process doing the I/O
si and so above 0, available lowMemoryps aux --sort=-rss, then the OOM lines in dmesg
st above a few percentThe host under the VMYour provider
Nothing stands outSomething outside the machineThe database, an API the app calls, DNS

Last checked on 24 October 2026 against Debian 12, Ubuntu 24.04, RHEL 9, procps-ng 4, and sysstat 12. If a step doesn’t match what you see, contact us with the command and what it printed.