Skip to content

Monitoring performance

Practical 5.7 monitoring-performance-annex.pdf · PDF

Your laptop is on. Nothing has crashed. No error window, no red dot. And yet every click takes two seconds and the fan sounds like a hair dryer. What is wrong?

In The case of the failed service the problem left a body: an exit code, a log line. A slow machine leaves nothing. No log ever says "I am slow". You have to measure. That is what a system administrator does when a colleague at Tramuntana Apps says "my machine is so slow" — and it is what you will do in Practical 5.7.

What you will learn

  • Name the four resources a machine can run out of — CPU, memory, disk, network — and one command to look at each
  • Read the load average and judge it against the number of cores
  • Read free -h and explain why available, not free, is the number that matters
  • Read the key columns of vmstat: r, b, si/so, bo, us/sy/id/wa
  • Take a baseline of a healthy machine and use it to find the bottleneck
  • Do the same on Windows with Task Manager, Resource Monitor and Get-Counter
  • Why "load average 2" is not "the CPU is at 2 %"

Slow is not broken: the four resources

Remember the kitchen from Unit 1: the CPU is the chef, RAM is the countertop, the disk is the pantry. Now picture Saturday night. The restaurant is full and dishes come out late. Before you shout at the chef, look at where things pile up. There are only four places:

Resource In the kitchen Look with Sign of trouble
CPU The chef's hands: one per core uptime, top, vmstat More dishes waiting than hands, for minutes
Memory The countertop free -h Almost nothing available; the system starts using swap
Disk The pantry and its one narrow door vmstat, iostat, df -h Processes queueing at the door, or the pantry is full
Network The delivery door ip -s link Errors or dropped packets that keep growing

The bottleneck is the slowest resource: it sets the pace of the whole system.

Unit 1 used this word for the road between CPU and RAM. Same idea here: hiring a second chef does nothing if the dishes are waiting at the pantry door. So the rule of the day is: measure first, buy later.

Load average: how many are waiting?

$ uptime
 20:54:41 up  1:52,  0 users,  load average: 4.73, 4.17, 2.59
$ nproc
12

The load average is the average number of processes that were running or waiting for a CPU over the last 1, 5 and 15 minutes.

nproc prints the number of cores. One load number alone means nothing: you always compare it with the cores. On that 12-core machine a load of 4.73 is a quiet afternoon. On your 2-vCPU deb-lab it would be a rush:

Load on 2 cores Kitchen with two hands
0.3 Mostly idle
2.0 Both hands busy, nobody waiting: full, not overloaded
6.0 Two dishes cooking, four waiting for a hand

Read the three numbers as a trend:

  • 6.0, 2.1, 0.8 — the last minute is the worst: it started a minute ago.
  • 0.8, 2.1, 6.0 — the last 15 minutes were the worst: it is over.

Careful: the load average is not a percentage

It is a count of processes, and it can be far above 100. Divide it by the number of cores in your head: load 2 on 2 cores is "full", load 2 on 16 cores is nearly idle.

The honest detail: Linux also counts the disk

On Linux the load also counts processes stuck waiting for the disk, not only for the CPU. It has been so since a patch by Matthias Urlichs in 1993, as the performance engineer Brendan Gregg traced in 2017. So a high load says "something is queueing" — CPU or disk. To know which one, you need the next tools.

Memory: why "free" lies

               total        used        free      shared  buff/cache   available
Mem:            30Gi        13Gi       460Mi       3.4Gi        19Gi        17Gi
Swap:           31Gi        12Ki        31Gi

That is free -h on a 31 GB machine (your 4 GB deb-lab shows about 3.8Gi total). Look: only 460 MiB free, but 17 GiB available. Is the machine out of memory? No.

Linux fills unused RAM with copies of files it has read from disk — the cache (buff/cache) — because empty RAM is wasted RAM. The moment a program needs the space, the cache gives it back.

Available is the honest number: how much memory programs could still get, counting the cache that can be given back.

In the kitchen: a countertop covered with ingredients you took out "just in case" is not a full countertop. You can clear it in a second.

Swap is a reserved area of the disk where the system moves memory that has not been used recently, when RAM really runs out.

Swap keeps the machine alive. But the disk is thousands of times slower than RAM (Unit 1), so a machine that swaps all the time feels frozen.

Careful: low free memory is normal

"Free memory is low, so I need more RAM" is the classic mistake. Look at available and at the swap columns of vmstat. Low free, high available and no swapping is a healthy Linux.

vmstat: one line, many clues

vmstat 1 5 prints one line per second, five times. Here is a calm line and a busy line from the same machine:

procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st gu
 2  0  11432 654344    928 20571848    0    0     0  3016 11144 27805  8  5 87  0  0  0
 6  0  78892 596348    928 20872744   16 7020 36912 76628 43531 48246 16 15 65  3  0  0
Column Meaning Worry when
r Processes running or waiting for a CPU It stays above the number of cores
b Processes blocked, waiting for the disk It stays above 0
si so Memory swapped in from / out to disk, per second They are not 0 for several lines: RAM is short
bi bo Blocks read from / written to disk, per second Context: who is doing all that I/O?
us sy % of CPU time in programs / in the kernel Together near 100
id % of CPU time idle Near 0
wa % of CPU time idle because it waits for the disk High for several lines: the disk is the bottleneck

Read the second line: r jumped to 6, bo went from 3,016 to 76,628 and so is 7,020. Something is writing hard to the disk and memory is being pushed to swap. One line of numbers, three clues.

Careful: skip the first line

The first line of vmstat is the average since boot, not "now". Read from the second line on.

The baseline: what healthy looks like

A baseline is a set of measurements of the machine when nothing is wrong.

Without it, numbers under load mean nothing: is wa 4 a lot? Only your baseline can say. Close the browser in the VM, wait one minute, and measure:

sudo apt install sysstat stress-ng   # iostat lives in sysstat; stress-ng creates load
nproc            # how many cores: 2 on deb-lab
uptime           # three numbers well below 2
free -h          # copy total, used, free, buff/cache, available
vmstat 1 5       # copy the LAST line
df -h /          # Use% well under 100
ip -s link       # RX/TX errors and dropped near 0 (the interface that is not lo)

On a resting deb-lab (2 vCPU, 4 GB, GNOME) expect: r 0–1, b 0, si/so 0, id above 90, wa 0–1. Your network interface has a name like enp1s0, not eth0.

Finding the bottleneck

In the Exercise sheet of Practical 5.7, three machines at Tramuntana Apps are "slow". A small script, mystery.sh, recreates each complaint for three minutes (bash mystery.sh A, then B, then C). You run the load in one terminal and measure in a second one — the first one is busy.

flowchart TB
    S["<b>It is slow</b><br>uptime: load above the cores?"] --> V["<b>vmstat 1 5</b><br>read from line 2"]
    V -->|"r high, id near 0,<br>us near 100"| CPU["<b>CPU</b><br>too few hands"]
    V -->|"si / so not 0,<br>available low in free -h"| MEM["<b>Memory</b><br>countertop full"]
    V -->|"b above 0, wa high,<br>bo huge, iostat busy"| DISK["<b>Disk</b><br>queue at the pantry door"]
    V -->|"all calm"| NET["<b>Network?</b><br>ip -s link: errors, dropped"]
    CPU --> WHO["<b>top</b><br>P sorts by CPU, M by memory:<br>who is doing it?"]
    MEM --> WHO
    DISK --> WHO

What each load looks like on deb-lab, compared with the baseline:

Load What you see Verdict Good advice Waste of money
A r about 4, id 0, us near 100, load heading for 4; stress-ng-cpu at the top of top CPU Find the process; stop it or lower its priority; more cores if it is the normal work More RAM
B available down by about 1.5 GiB; stress-ng-vm at the top with M; CPU almost idle Memory Find what uses the memory; more RAM if it is needed A faster CPU
C bo in the thousands, b 1 or more, wa above the baseline; iostat -d 1 3 shows vda writing a lot; load rises with the CPU not busy Disk Find what writes so much; a faster disk (SSD) or run the job at night More RAM

Load C is the 1993 detail live: the load average goes up although the CPU is not working hard.

Careful: two kinds of percentage in top

The %Cpu(s) summary line at the top is the whole machine. The %CPU column of each process is per core, so one process can show 99 % on a machine that is half idle — you saw this in Processes.

The Windows side

Windows looks at the same four resources with different tools:

  • Task Manager (Ctrl+Shift+Esc) → Performance: one graph each for CPU, Memory, Disk and Ethernet. The Processes page, sorted by a column, says who is responsible.
  • Resource Monitor (Win+R → resmon, or the link at the bottom of the Performance page): tabs Overview, CPU, Memory, Disk and Network, process by process.
  • Get-Counter in PowerShell, for the command line:
Get-Counter '\Processor(_Total)\% Processor Time' -SampleInterval 2 -MaxSamples 3
Get-Counter '\Memory\Available MBytes'
Resource Linux Windows
CPU uptime, top, vmstat Task Manager → Performance → CPU
Memory free -h Performance → Memory ("In use", "Available")
Disk iostat, vmstat (wa, bo), df -h Performance → Disk ("Active time"); Resource Monitor → Disk
Network ip -s link Performance → Ethernet
Who is doing it top (P, M) Processes page, sorted; Resource Monitor
Command line All of the above Get-Counter

Windows has no load average; CPU % and the graphs are enough for this course.

Try the smallest CPU load there is, in a PowerShell window of win11:

while ($true) { }

It keeps one core at 100 %. On the 2-vCPU win11, the CPU graph settles near 50 %. Task Manager shows the percentage of the whole machine: one busy core out of two. Ctrl+C stops the loop and the graph falls back.

Careful: 50 % does not mean half is free

On a 2-core machine, 50 % can mean one program is stuck using a whole core. Same lesson as the per-core column in top, seen from the other side.

Key takeaways

  • A slow machine runs out of one of four resources: CPU, memory, disk or network. The slowest one is the bottleneck.
  • The load average counts processes running or waiting over 1, 5 and 15 minutes. Compare it with nproc; on Linux it also counts processes waiting for the disk.
  • In free -h, trust available, not free: the cache is given back when programs need it. Constant swap is the real sign of short RAM.
  • In vmstat, skip line one: r and id speak about the CPU, si/so about memory, b, wa and bo about the disk.
  • A baseline of the healthy machine is what makes the numbers under load meaningful. Measure before you buy.
  • On Windows: Task Manager, Resource Monitor and Get-Counter show the same four resources as a percentage of the whole machine.

Quick check

1. uptime shows load average: 6.00, 5.80, 5.50 on a machine with 2 cores. What does it mean?
  • About four processes are waiting for a CPU all the time
  • The CPU is at 6 % of its capacity
  • Six users are logged in at the moment
  • The machine has been switched on for 6 hours

The load average is a count of processes running or waiting, not a percentage. Two can run on 2 cores, so about four are waiting, and the three numbers show it has lasted at least 15 minutes.

2. free -h shows free 180Mi and available 2.4Gi. Is the machine short of memory?
  • No: programs can still get about 2.4 GiB
  • Yes: only 180 MiB are left for programs
  • Yes: it must be swapping all the time
  • It cannot be known from the output of free

Linux fills idle RAM with cache and gives it back on demand. Available counts that, so it is the honest number; low free is normal on a healthy machine.

3. In vmstat, what does a high value in the wa column tell you?
  • The CPU is idle because it is waiting for the disk
  • The CPU is busy running programs
  • Memory is being moved to swap
  • The network card is dropping packets

wa is the share of CPU time spent waiting for the disk. High wa for several lines, together with b above 0, points at the disk as the bottleneck.

4. Which pair of vmstat columns shows that RAM has really run out?
  • si and so
  • us and sy
  • r and b
  • bi and bo

si and so are memory swapped in and out per second. When they stay above 0, the system is using swap because RAM is short — and the machine feels frozen.

5. Why do you take a baseline before looking at a slow machine?
  • Without numbers from a healthy state, the numbers under load cannot be judged
  • The baseline makes the machine faster before the test
  • vmstat refuses to run until a baseline has been saved
  • The baseline deletes the cache so the results are cleaner

A baseline is what the machine looks like when nothing is wrong. Is wa 4 a lot? Is bo 3,000 a lot? Only the comparison with your own calm machine can tell.

6. On a 2-vCPU Windows VM, one PowerShell loop keeps the CPU graph of Task Manager at about 50 %. Why not 100 %?
  • One core is fully busy and Task Manager shows the whole machine
  • Windows reserves half of the CPU for itself
  • PowerShell is limited to half the CPU by design
  • The graph only reaches 100 % when the disk is busy too

The loop keeps one core at 100 %. Task Manager shows the percentage of the whole machine, so one busy core out of two is 50 %.

7. A Tramuntana Apps server is slow: us is 5, wa is 40 for minutes, available is large. Select the two that are true.
  • The evidence points at the disk as the bottleneck
  • Buying more RAM would be a waste of money
  • A faster CPU will solve the problem
  • The machine is short of memory and swapping

A high wa for minutes means the CPU sits waiting for the disk, while large available says memory is fine and us 5 says the CPU is nearly idle. The fix is to find what is writing so much, or a faster disk — not RAM, not a CPU.

Next: now that you can read a machine, change it — its name, its clock, its language and its PATH — in Configuring the system by command.