Linux Performance & Resource Telemetry: USE Method, Load Average, PSI (/proc/pressure), Page Cache & eBPF
Executive Summary: Misinterpreting Linux Load Average as "CPU usage only" or panicking because
free -hshows lowfreeRAM (ignoring reclaimable Page Cache inavailable) leads to misdiagnosed bottlenecks. This architectural guide applies Brendan Gregg's USE Method (Utilization, Saturation, Errors) across the four core kernel subsystems—CPU, Memory, Storage I/O, and Network—covering Linux Pressure Stall Information (PSI),vmstat,iostat -xz,pidstat,perf, and eBPF (bpftrace/bcc).
-
Linux Load Average &
R+DTasks
Understand why Linux Load Average includes both CPU-runnable (
R) and Uninterruptible Disk/NFS Wait (D) tasks (vmstat 1). -
Pressure Stall Information (PSI)
Read kernel
/proc/pressure/{cpu,memory,io}metrics (somevs.full) to quantify exact millisecond resource stalls across cgroups. -
Page Cache vs.
availableMemory
Distinguish anonymous process heap pages from reclaimable VFS Page Cache (
Cached/SReclaimable) and diagnose OOM-killer events. -
Block Layer I/O Latency (
iostat -xz)
Separate queue saturation (
aqu-sz) from physical NVMe hardware service latency (r_await,w_await) usingsysstat.
1. Architecture: The 60-Second Linux Observability Checklist
When logging into an unresponsive or degraded production Linux server, execute the 60-Second Linux Performance Checklist to isolate whether saturation is occurring in CPU runqueues, memory page reclaim (kswapd0), storage block queues, or network softirqs:
%%{init: {'flowchart': {'wrappingWidth': 600}}}%%
flowchart TD
Incident["Degraded Server Login"] --> Step1["1. uptime & /proc/pressure/*<br/>(Check Load Avg + PSI Stalls)"]
Step1 --> Step2["2. dmesg -T | tail -n 30<br/>(OOM Killer / NVMe / XFS Errors?)"]
Step2 --> Step3["3. vmstat 1 5<br/>(r = CPU Runqueue, b = I/O Blocked,<br/>si/so = Swap Thrashing)"]
Step3 --> Branch{"Where is the Saturation?"}
Branch -->|"High us/sy + r > Cores"| CPU["mpstat -P ALL 1<br/>pidstat -u 1 / perf top"]
Branch -->|"High si/so or PSI memory"| Mem["free -h & smaps_rollup<br/>slabtop / dmesg OOM"]
Branch -->|"High wa/b or PSI io"| Disk["iostat -xz 1<br/>iotop-c / pidstat -d 1"]
Branch -->|"High si (softirq)"| Net["sar -n DEV,ETCP 1<br/>ss -s / ip -s link"]
Why Linux Load Average Spikes Even When CPU Usage is 0%
On other UNIX systems, Load Average measures only threads waiting on the CPU runqueue (R state). In the Linux kernel (kernel/sched/loadavg.c), exponentially damped 1-, 5-, and 15-minute Load Averages count nr_running (R state) PLUS nr_uninterruptible (D state). Consequently, if a network storage mount (NFS/iSCSI) or degraded disk stalls 30 worker threads in D state, your Load Average will climb to 30.00 even though CPU utilization is 0.5%!
2. Kernel Pressure Stall Information (PSI — /proc/pressure/*)
Introduced in Linux 4.20+, Pressure Stall Information (PSI) provides a far more accurate saturation metric than Load Average by measuring the exact percentage of wall-clock time tasks were stalled waiting for CPU, Memory (page fault / kswapd reclaim), or I/O over the last 10s, 60s, and 300s:
some: Percentage of time at least one task was delayed waiting for the resource.full: Percentage of time ALL non-idle tasks were simultaneously stalled waiting for the resource (zero productive forward progress).
head -n 5 /proc/pressure/cpu /proc/pressure/memory /proc/pressure/io
==> /proc/pressure/io <==
some avg10=42.15 avg60=18.40 avg300=5.12 total=84920144
full avg10=31.08 avg60=12.10 avg300=2.85 total=51209412
3. CPU, Memory & Virtual Memory Telemetry (vmstat, mpstat, free)
Install the sysstat package (sudo apt install sysstat) to unlock mpstat, iostat, pidstat, and sar.
# 1. Watch system-wide runqueue (r), blocked I/O tasks (b), swap in/out (si/so), and CPU % every 1s
# Note: Always ignore the first summary line of vmstat/iostat (it shows averages since boot!)
vmstat 1 5
# 2. Check per-core CPU utilization and hardware/software interrupt ( %irq / %soft ) imbalance
mpstat -P ALL 1 3
# 3. Inspect RAM usage: Look at the 'available' column (NOT 'free'!), as Linux uses spare RAM for Page Cache
free -h
# 4. Inspect kernel slab caches (dentry, ext4_inode_cache, kmalloc)
sudo slabtop -o -s c | head -n 20
vmstat 1 Column |
Subsystem | Healthy Baseline vs. Saturation Signal |
|---|---|---|
r |
CPU Runqueue | Number of threads running or waiting for CPU time. Saturation occurs when r consistently exceeds physical CPU core count (nproc). |
b |
Storage / Locks | Number of threads stuck in Uninterruptible Sleep (D state). Should be 0; sustained b > 0 indicates disk/NFS bottlenecks. |
si / so |
Virtual Memory | Pages swapped in/out per second from disk/zram. Non-zero sustained si/so combined with high wa indicates severe swap thrashing. |
us / sy / wa |
CPU Time % | User time (us), Kernel syscall time (sy), and I/O Wait idle time (wa). High sy (> 30%) indicates excessive context switching or lock contention. |
4. Storage Block I/O & Per-Process Attribution (iostat -xz & pidstat)
When vmstat or /proc/pressure/io indicates storage contention, use iostat -xz 1 to inspect block-device latency and pidstat -d 1 to identify the exact offending PID:
# 1. Inspect extended device statistics (-x), omitting zero-activity devices (-z) every 1 second
iostat -xz 1 3
# 2. Pinpoint the exact PID and command generating disk reads/writes (kB_rd/s, kB_wr/s)
pidstat -d 1 5
Interpreting iostat -xz on Modern NVMe Drives
r_await/w_await: Average time (in milliseconds) for read/write I/O requests to be serviced (including queue time + hardware execution). On local NVMe storage,r_awaitandw_awaitshould be< 1.0 ms. Values exceeding10–20 msindicate saturation or failing media.aqu-sz(Average Queue Size): Average number of I/O requests queued and in flight.%util: Caveat on NVMe:%utilmeasures the percentage of time at least one request was active. Because NVMe drives process up to 64,000 queues in parallel,%utilcan hit100%long before a multi-queue NVMe SSD is actually saturated—always judge NVMe saturation byr_await/w_awaitandaqu-sz.