| name | system-performance |
| description | Use when analyzing system performance, debugging performance issues, investigating bottlenecks, or when the user mentions "performance analysis", "USE method", "flame graphs", "Brendan Gregg", or "system performance". |
System Performance Analysis
Overview
System performance analysis is a methodology for investigating and solving performance problems in computing systems. This skill provides structured approaches based on Brendan Gregg's performance analysis methodologies, including the USE Method, RED Method, flame graphs, and other systematic debugging techniques.
When to Use
Use this skill when:
- Investigating performance bottlenecks
- Debugging slow systems or applications
- Analyzing CPU, memory, disk, or network performance
- The user mentions "performance analysis", "USE method", "flame graphs", or "Brendan Gregg"
- Conducting performance testing or benchmarking
- Optimizing system or application performance
Core Methodologies
1. USE Method (Utilization, Saturation, Errors)
For every resource, check utilization, saturation, and errors.
The USE Method is most effective for finding resource bottlenecks early in a performance investigation.
Resource Types
Physical Resources:
- CPUs: sockets, cores, hardware threads (virtual CPUs)
- Memory: capacity
- Network interfaces
- Storage devices: I/O, capacity
- Controllers: storage, network cards
- Interconnects: CPUs, memory, I/O
Software Resources:
- Mutex locks
- Thread pools
- Process/thread capacity
- File descriptor capacity
Metrics
| Resource | Utilization | Saturation | Errors |
|---|
| CPU | CPU utilization (per-CPU or system-wide) | Run-queue length or scheduler latency | Correctable CPU cache ECC events |
| Memory | Available free memory (system-wide) | Anonymous paging or thread swapping | Failed malloc()s |
| Network | RX/TX throughput / max bandwidth | Dropped packets, overruns | Interface errors |
| Storage I/O | Device busy percent | Wait queue length | Device errors |
| Storage Capacity | Used vs total capacity | Allocation failures | Filesystem errors |
Interpretation Guidelines
Utilization:
- 100% utilization is usually a sign of a bottleneck
- High utilization (>70%) can begin to be a problem:
- Long time periods can hide short bursts of 100%
- Some resources (disks) cannot be interrupted during operations
Saturation:
- Any degree of saturation can be a problem (non-zero)
- Measured as queue length or time spent waiting
Errors:
- Non-zero error counters are worth investigating
- Especially if they are still increasing while performance is poor
USE Method Flowchart
Start
↓
For each resource:
↓
Check errors → If errors found → Investigate
↓
Check utilization → If high utilization → Check saturation
↓ ↓
Check saturation → If saturation → Investigate
↓
Next resource
2. RED Method (Rate, Errors, Duration)
For every service or microservice, check request rate, errors, and duration.
The RED Method is designed for monitoring services and microservices, focusing on request-driven metrics.
Metrics
| Metric | Description | Measurement |
|---|
| Rate | Requests per second | Counter over time window |
| Errors | Failed requests per second | Error count / time |
| Duration | Request latency distribution | Histogram (p50, p95, p99) |
Application
For each service:
- Rate: Measure requests per second
- Errors: Count failed requests
- Duration: Track latency percentiles
3. TSA Method (Thread State Analysis)
For each thread of interest, measure time in operating system thread states.
Thread States
- Executing: Running on-CPU
- Runnable: Ready to run, waiting for CPU
- Swapping: Waiting for memory pages
- Sleeping: Waiting for an event
- Lock: Waiting for a lock
- Idle: Thread is idle
Process
- Identify threads of interest
- Measure time in each state
- Investigate states from most to least frequent
- Use appropriate tools for each state
4. Flame Graphs
Visualize CPU usage with stack traces.
Flame graphs show which code paths are consuming CPU time, making it easy to identify hot spots.
Types
- CPU Flame Graphs: On-CPU time
- Off-CPU Flame Graphs: Off-CPU time (waiting)
- Memory Flame Graphs: Memory allocations
- I/O Flame Graphs: I/O operations
Reading Flame Graphs
- X-axis: Stack profile population (not time)
- Y-axis: Stack depth
- Width: Proportion of samples in that stack
- Color: Can indicate different dimensions (process, thread, etc.)
Generation
perf record -g -p <PID>
perf script | stackcollapse-perf.pl | flamegraph.pl > cpu.svg
perf record -e sched:sched_switch -g -p <PID>
perf script | stackcollapse-perf.pl | flamegraph.pl > offcpu.svg
bpftrace -e 'profile:hz:99 @[ustack] = count();' > out.stacks
cat out.stacks | flamegraph.pl > cpu.svg
Performance Analysis Workflow
Problem Statement Method
Start by asking:
- What makes you think there is a performance problem?
- Has this system ever performed well?
- What has changed recently? (Software? Hardware? Load?)
- Can the performance degradation be expressed in terms of latency or run time?
- Does the problem affect other people or applications (or is it just you)?
- What is the environment? What software and hardware is used? Versions? Configuration?
Workload Characterization Method
- Who is causing the load? (PID, UID, IP addr, customer ID, geographic region, ...)
- Why is the load called? (code path, stack trace, flame graph)
- What is the load? (IOPS, throughput, type, url)
- How is the load changing over time? (time series line graph)
Drill-Down Analysis Method
- Start at highest level
- Examine next-level details
- Pick most interesting breakdown
- If problem unsolved, go to 2
Process of Elimination
- Divide the target into components
- Choose a test which:
- Can exonerate many untested components (ideally, half of those remaining)
- Is quick to perform
- Perform test
- Were the tested components exonerated?
- Yes: go to 2
- No: problem found?
- Yes: done
- No: how many components were tested?
- one: target = tested component; go to 1
- multiple: go to 2 and choose a different test
Anti-Methodologies (What NOT to Do)
Blame-Someone-Else Anti-Method
- Find a system or environment component you are not responsible for
- Hypothesize that the issue is with that component
- Redirect the issue to the responsible team
- When proven wrong, go to 1
Streetlight Anti-Method
- Pick observability tools that are:
- familiar
- found on the Internet
- found at random
- Run tools
- Look for obvious issues
Drunk Man Anti-Method
- Change things at random until the problem goes away
Random Change Anti-Method
- Measure a performance baseline
- Pick a random attribute to change (eg, a tunable)
- Change it in one direction
- Measure performance
- Change it in the other direction
- Measure performance
- Were the step 4 or 6 results better than the baseline? If so, keep the change; if not, revert
- Goto step 1
Passive Benchmarking Anti-Method
- Pick a benchmark tool
- Run it with a variety of options
- Make a slide deck of the results
- Hand the slides to management
Traffic Light Anti-Method
- Open dashboard
- All green? Assume everything is good.
- Something red? Assume that's a problem.
Linux Performance Tools
System-Wide
top, htop, mpstat
free, vmstat
iostat, iotop
netstat, ss, ip, ifconfig
dstat, vmstat, mpstat
Advanced Tools
strace, ltrace
perf
bpftrace, bcc tools
bpftrace, bcc
CPU Analysis
mpstat 1
top -P
perf record -g -a sleep 60
perf script | stackcollapse-perf.pl | flamegraph.pl > cpu.svg
perf sched record -- sleep 60
perf sched latency
offcputime -p <PID>
Memory Analysis
free -m
vmstat 1
ps -o pid,comm,maj_flt,min_flt -p <PID>
valgrind --leak-check=full <program>
wss <PID>
perf record -e page-faults -g -p <PID>
Disk I/O Analysis
iostat -x 1
iotop
biolatency
filetop -p <PID>
Network Analysis
sar -n DEV 1
ss -s
netstat -s
ping, traceroute, mtr
tcpdump, wireshark
perf record -e net:* -g -a
Performance Mantras
- Don't do it - The fastest code is no code
- Do it, but don't do it again - Cache results
- Do it less - Optimize algorithms
- Do it later - Defer work to background
- Do it when they're not looking - Batch operations
- Do it concurrently - Parallelize work
- Do it cheaper - Use cheaper resources
Benchmarking Checklist
Before trusting benchmark results, ask:
- Why not double? - If performance doesn't double with double resources, there's a bottleneck
- Did it break limits? - Check for resource limits (CPU, memory, I/O)
- Did it error? - Check for errors that may have been ignored
- Does it reproduce? - Run multiple times to check consistency
- Does it matter? - Is the difference statistically significant?
- Did it even happen? - Verify the benchmark actually ran as expected
Active Benchmarking
Instead of passive benchmarking (run and observe), use active benchmarking:
- Configure the benchmark to run for a long duration
- While running, analyze performance using other tools
- Determine limiting factors
- Understand why performance is what it is
Common Performance Issues
CPU Issues
Symptoms:
- High CPU utilization
- Slow response times
- Run queue saturation
Investigation:
mpstat 1
vmstat 1
perf record -g -a sleep 60
perf script | stackcollapse-perf.pl | flamegraph.pl > cpu.svg
Common Causes:
- Inefficient algorithms
- Excessive loops
- Unnecessary computations
- Lock contention
Memory Issues
Symptoms:
- High memory utilization
- Page faults
- Out of memory errors
- Swap usage
Investigation:
free -m
vmstat 1
ps -o pid,comm,maj_flt,min_flt -p <PID>
wss <PID>
Common Causes:
- Memory leaks
- Large data structures
- Inefficient caching
- Memory fragmentation
Disk I/O Issues
Symptoms:
- High disk utilization
- I/O wait times
- Slow file operations
Investigation:
iostat -x 1
biolatency
iotop
Common Causes:
- Random I/O patterns
- Small I/O sizes
- Synchronous I/O
- Disk fragmentation
Network Issues
Symptoms:
- High network utilization
- Packet loss
- High latency
- Connection timeouts
Investigation:
sar -n DEV 1
ss -s
netstat -s
ping, traceroute
Common Causes:
- Network congestion
- Packet loss
- DNS issues
- Firewall rules
Performance Analysis Steps
Step 1: Problem Statement
Define the performance problem clearly:
- What is the symptom?
- When did it start?
- What changed?
- What is the impact?
Step 2: USE Method
Apply USE Method to identify resource bottlenecks:
- Check CPU, memory, disk, network
- Look for high utilization, saturation, errors
Step 3: Workload Characterization
Understand the workload:
- Who is causing the load?
- What type of load?
- How is it changing?
Step 4: Drill-Down Analysis
Drill down into identified bottlenecks:
- Use appropriate tools
- Generate flame graphs
- Analyze stack traces
Step 5: Root Cause Analysis
Identify the root cause:
- Use process of elimination
- Test hypotheses
- Verify fixes
Quick Reference
| Method | Use Case | Key Metrics |
|---|
| USE Method | Resource bottlenecks | Utilization, Saturation, Errors |
| RED Method | Services/microservices | Rate, Errors, Duration |
| TSA Method | Thread analysis | Time in each state |
| Flame Graphs | CPU hot spots | Stack traces |
| Workload Char | Understanding load | Who, Why, What, How |
| Drill-Down | Deep analysis | Hierarchical breakdown |
Tools Quick Reference
| Tool | Purpose |
|---|
top, htop | Process CPU/memory |
mpstat | CPU statistics |
vmstat | Virtual memory |
iostat | Disk I/O |
netstat, ss | Network statistics |
perf | Performance counters |
bpftrace | BPF tracing |
flamegraph.pl | Flame graph generation |
The Bottom Line
System performance analysis requires a systematic approach. Start with the USE Method to identify resource bottlenecks, use flame graphs to visualize CPU usage, apply workload characterization to understand the load, and drill down to find root causes. Avoid anti-methodologies like random changes or passive benchmarking. Always verify your findings and understand why performance is what it is.