open atlas
↑ Back to track
Command line CLI · 07 · 04

Monitoring resources

top and htop give real-time per-process CPU and memory. Load average tells you how many processes are competing for CPU averaged over 1, 5, and 15 minutes. free shows RAM and swap usage in one line. Together these three answer: is the machine healthy right now?

CLI Middle ◷ 22 min
Level
FoundationsJuniorMiddleSenior

A server running at 100% CPU for 30 seconds might be fine — a short batch job. The same server at 100% for 30 minutes is a crisis. Load average over 15 minutes above your CPU count means you have a queue of waiting processes. Memory at 95% with zero swap used is probably fine; memory at 95% with active swap is the leading indicator of an imminent OOM kill. Reading these numbers correctly — not just seeing them — is the difference between a calm on-call rotation and a 3 AM panic.

Goal

After this lesson you can interpret top and htop output for CPU and memory per process, read load average and explain what numbers above core count mean, use free -h to assess memory and swap pressure, and use uptime to get a quick system health check.

1

top is the classic real-time process monitor. It refreshes every 3 seconds (configurable). The header shows system-wide stats; the process table below is sorted by %CPU by default.

top - 10:42:17 up 2 days, 14:03,  2 users,  load average: 1.23, 0.87, 0.64
Tasks: 182 total,   2 running, 180 sleeping,   0 stopped,   0 zombie
%Cpu(s):  8.3 us,  1.2 sy,  0.0 ni, 89.1 id,  1.0 wa,  0.0 hi,  0.4 si
MiB Mem :   7822.4 total,    412.1 free,   5631.3 used,   1779.0 buff/cache
MiB Swap:   2048.0 total,   2048.0 free,      0.0 used.   1823.1 avail Mem

Key CPU fields in the %Cpu row:

  • us — user-space CPU time (your application code)
  • sy — kernel/system CPU time (syscalls, I/O handling)
  • id — idle percentage (100 - id = total utilisation)
  • wa — I/O wait — CPU sitting idle waiting for disk or network; high wa = I/O bottleneck, not CPU

Interactive commands inside top: q quit, k kill (prompts for PID + signal), M sort by memory, P sort by CPU, 1 toggle per-core view.

2

Load average: three numbers, one concept. The three values from uptime or the top header are the average number of processes in the run queue (running or waiting for CPU) over the last 1, 5, and 15 minutes.

uptime
# 10:42:17 up 2 days, load average: 1.23, 0.87, 0.64

Rule of thumb: compare load to your CPU count (nproc or /proc/cpuinfo). On a 4-core machine:

  • Load 2.0 → 50% of CPU capacity used on average. Fine.
  • Load 4.0 → 100% utilisation. Every job that arrives must wait if others are running.
  • Load 8.0 → 200% — you have a 4-process queue on average. Something is wrong.

Trend matters more than the instant snapshot. Load 6.0, 3.0, 1.5 is falling — a burst just ended. Load 1.5, 3.0, 6.0 is rising — investigate now. Load includes processes in uninterruptible I/O wait (D state), so very high load with low %CPU usually means an I/O bottleneck.

3

free -h shows RAM and swap in human-readable units.

free -h
#               total        used        free      shared  buff/cache   available
# Mem:           7.6G        5.5G        402M        312M       1.7G       1.8G
# Swap:          2.0G          0B        2.0G

The column that matters is available, not free. Linux aggressively uses free RAM as a page cache (buff/cache). That memory is instantly reclaimable when a process needs it — it is not “used” in any meaningful sense. available = free + reclaimable cache = what a new process can actually get.

Swap: swap used > 0 means the kernel has started evicting cold pages to disk. A small amount is normal. Active swapping (watch vmstat 1 for the si/so columns) causes visible latency. Swap fully used with swap activity is the last warning before OOM kills start.

free -h          # human-readable
free -s 2        # refresh every 2 seconds
vmstat 1         # per-second view: si/so = swap in/out pages
4

htop is a friendlier top with mouse support and colour. It is not installed by default but is available in every major distro’s package manager.

sudo apt install htop    # Debian/Ubuntu
sudo dnf install htop    # RHEL/Fedora
htop

Key advantages over top:

  • Colour-coded CPU bars per core (instantly see if one core is saturated while others are idle)
  • Scrollable process list — no truncation
  • F6 to sort by any column interactively
  • F9 to send a signal with a menu (no need to type the number)
  • F5 tree view — shows parent-child relationships inline
  • Filter by username or process name with \

For routine monitoring on servers where you control the environment, install htop. For read-only diagnostics on unfamiliar machines, top is always available.

5

Quick one-liner health checks. When you SSH into a machine and need a 10-second triage:

uptime                        # load average trend
free -h                       # memory and swap
ps aux --sort=-%cpu | head    # top CPU consumers
ps aux --sort=-%mem | head    # top memory consumers
df -h                         # disk usage (often forgotten until full)

Combine into a reusable alias:

alias health='uptime && free -h && df -h'

For sustained monitoring, redirect top -b -n 5 (batch mode, 5 iterations) to a file for a time-stamped snapshot you can share or diff.

Worked example

Diagnose a slow server in under 2 minutes.

# 1. Is load high? Is it rising or falling?
uptime
# load average: 7.81, 4.32, 2.11  ← rising on a 4-core box. Bad.

# 2. Is it CPU-bound or I/O-bound?
top -bn1 | head -5
# %Cpu: 12.3 us, 3.1 sy, 0.0 ni, 21.4 id, 62.8 wa
# 62.8% wa → I/O wait. Not CPU-bound.

# 3. Which process is doing the I/O?
ps aux --sort=-%cpu | head -5
# Shows low CPU... but load is high because processes are in D state.

# 4. Find D-state processes
ps aux | awk '$8 ~ /^D/ {print}'
# postgres  4219 0.1  2.3 ... D  ... postgres: checkpointer
# Disk I/O from postgres checkpointer is blocking the run queue.

# 5. Check disk
df -h /var/lib/postgresql
# 97% full — write I/O is stalling because the filesystem is nearly full.

Root cause: disk nearly full → writes stall → postgres checkpointer blocks in D state → load average climbs even though %CPU is low. Fix: free disk space.

Why this works

On macOS, top output format differs significantly — the columns have different names and order. htop is available via Homebrew. Load average on macOS includes sleeping processes that are not competing for CPU, which can make the numbers higher than Linux equivalents. The free command does not exist on macOS; use vm_stat or Activity Monitor instead. For production Linux systems, the tools in this lesson work identically across all major distributions.

Common mistake

Using the free column from free output to assess memory pressure is the most common misreading. On a healthy Linux system, free RAM is nearly zero because the kernel fills spare memory with page cache. “Low free” with high available is fine. “Low available” with active swap (si/so > 0 in vmstat) is the real warning sign. Never alarm on free RAM alone.

Check yourself
Quiz

A 4-core server shows load average: 6.5, 5.2, 3.1 and top shows %Cpu: 15us, 5sy, 78id, 2wa. What is the most likely explanation?

Recap

top refreshes system and per-process stats in real time; sort by memory with M, per-core view with 1. Load average (from uptime or top header) counts the average run-queue depth over 1/5/15 minutes — compare to nproc; rising load above core count needs investigation. free -h: watch the available column, not free; active swap (vmstat si/so > 0) is the real pressure signal. htop adds colour, mouse, and tree view — install it on servers you control. For quick triage: uptime, free -h, ps aux --sort=-%cpu | head.

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 4 done

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.