
Flamegraphs
- 353 installs
- 155 repo stars
- Updated June 27, 2026
- mohitmishra786/low-level-dev-skills
Profile CPU-bound native services, generate flame graphs from perf or similar traces, and pinpoint hot stacks causing latency regressions before production rollout.
About
Walks through capturing stack samples and rendering flame graphs for C/C++ and systems workloads. Shows how to fold traces, read plateaus, and prioritize optimizations in APIs, CLIs, and multi-tenant SaaS backends.
- perf record and script folding
- Stack collapse format rules
- Inclusive versus exclusive hotspots
- Kernel and userspace mixed stacks
- Regression comparison across builds
Flamegraphs by the numbers
- 353 all-time installs (skills.sh)
- +24 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #114 of 596 Debugging skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill flamegraphsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 353 |
|---|---|
| repo stars | ★ 155 |
| Last updated | June 27, 2026 |
| Repository | mohitmishra786/low-level-dev-skills ↗ |
What it does
Profile CPU-bound native services, generate flame graphs from perf or similar traces, and pinpoint hot stacks causing latency regressions before production rollout.
Files
Flamegraphs
Purpose
Guide agents through the pipeline from profiler data to SVG flamegraph, and teach interpretation of flamegraphs to drive concrete optimisation decisions.
Triggers
- "How do I generate a flamegraph from perf data?"
- "How do I read a flamegraph?"
- "The flamegraph shows a wide frame — what does that mean?"
- "How do I generate a flamegraph from Callgrind?"
- "I want to compare two flamegraphs (before/after)"
Workflow
1. Install FlameGraph tools
git clone https://github.com/brendangregg/FlameGraph
# No install needed; scripts are in the repo
export PATH=$PATH:/path/to/FlameGraph2. perf → flamegraph (most common path)
# Step 1: record
perf record -F 999 -g -o perf.data ./prog
# Step 2: generate script output
perf script -i perf.data > out.perf
# Step 3: collapse stacks
stackcollapse-perf.pl out.perf > out.folded
# Step 4: generate SVG
flamegraph.pl out.folded > flamegraph.svg
# Step 5: view
xdg-open flamegraph.svg # Linux
open flamegraph.svg # macOSOne-liner:
perf record -F 999 -g ./prog && perf script | stackcollapse-perf.pl | flamegraph.pl > fg.svg3. Differential flamegraph (before/after)
# Collect two profiles
perf record -g -o before.data ./prog_old
perf record -g -o after.data ./prog_new
# Collapse
perf script -i before.data | stackcollapse-perf.pl > before.folded
perf script -i after.data | stackcollapse-perf.pl > after.folded
# Diff (red = regressed, blue = improved)
difffolded.pl before.folded after.folded | flamegraph.pl > diff.svg4. Callgrind → flamegraph
valgrind --tool=callgrind --callgrind-out-file=cg.out ./prog
stackcollapse-callgrind.pl cg.out | flamegraph.pl > fg.svg5. Other profiler inputs
# Go pprof
go tool pprof -raw -output=prof.txt prog
stackcollapse-go.pl prof.txt | flamegraph.pl > fg.svg
# DTrace
dtrace -x ustackframes=100 -n 'profile-99 /execname=="prog"/ { @[ustack()] = count(); }' \
-o out.stacks sleep 10
stackcollapse.pl out.stacks | flamegraph.pl > fg.svg
# Java (async-profiler)
async-profiler -d 30 -f out.collapsed PID
flamegraph.pl out.collapsed > fg.svg6. Reading flamegraphs
A flamegraph is a call-stack visualisation:
- X axis: time on CPU (not time sequence) — wider = more time
- Y axis: call stack depth — taller = deeper call chain
- Color: random (no significance) — unless using differential mode
What to look for:
| Pattern | Meaning | Action |
|---|---|---|
| Wide frame near bottom | Function itself is hot | Optimise that function |
| Wide frame with tall narrow towers | Calling many different callees | Hot dispatch; reduce call overhead |
| Very tall stack with wide base | Deep recursion | Check recursion depth; consider iterative approach |
| Plateau at the top | Leaf function with no callees | This leaf is the actual hotspot |
| Many narrow identical stacks | Many threads doing the same work | Consider parallelism or batching |
Identifying the actionable hotspot:
1. Find the widest top frame (a frame with no or narrow children above it) 2. That is where CPU time is actually spent 3. Trace down to understand what called it and why
Differential flamegraph:
- Red frames: more time in new profile (regression)
- Blue frames: less time in new profile (improvement)
- Frames only in one profile appear solid colored
7. flamegraph.pl options
flamegraph.pl --title "My App" \
--subtitle "Release build, workload X" \
--width 1600 \
--height 16 \
--minwidth 0.5 \
--colors java \
out.folded > fg.svg| Option | Effect |
|---|---|
--title | SVG title |
--width | Width in pixels |
--height | Frame height in pixels |
--minwidth | Omit frames < N% (reduces clutter) |
--colors | Palette: hot (default), mem, io, java, js, perl, red, green, blue |
--inverted | Icicle chart (roots at top) |
--reverse | Reverse stacks |
--cp | Consistent palette (same frame = same color across SVGs) |
References
For tool installation, stackcollapse scripts, and palette options, see references/tools.md.
Related skills
- Use
skills/profilers/linux-perfto collect perf data - Use
skills/profilers/valgrindto collect Callgrind data - Use
skills/compilers/clangfor LLVM PGO from sampling profiles
Flamegraph Tools Reference
Source: <https://github.com/brendangregg/FlameGraph> Source: <https://www.brendangregg.com/flamegraphs.html>
Table of Contents
1. FlameGraph scripts 2. stackcollapse scripts by profiler 3. flamegraph.pl options 4. Differential flamegraphs 5. Alternative flamegraph tools 6. Reading patterns quick reference
---
FlameGraph scripts
All from: git clone https://github.com/brendangregg/FlameGraph
| Script | Purpose |
|---|---|
stackcollapse-perf.pl | Collapse perf script output |
stackcollapse-callgrind.pl | Collapse Valgrind Callgrind output |
stackcollapse-gprof.pl | Collapse gprof output |
stackcollapse-go.pl | Collapse Go pprof raw output |
stackcollapse-stap.pl | Collapse SystemTap output |
stackcollapse-dtrace.pl | Collapse DTrace stacks |
stackcollapse-jstack.pl | Collapse Java jstack output |
stackcollapse-ljp.pl | Collapse Lightweight Java Profiler |
stackcollapse.pl | Generic collapse (DTrace format) |
flamegraph.pl | Generate SVG flamegraph |
difffolded.pl | Diff two folded stack files |
record-test.sh | Example perf recording script |
---
stackcollapse scripts by profiler
Linux perf
perf record -F 999 -g -o perf.data ./prog
perf script -i perf.data > out.perf
stackcollapse-perf.pl out.perf > out.folded
flamegraph.pl out.folded > fg.svgValgrind Callgrind
valgrind --tool=callgrind --callgrind-out-file=cg.out ./prog
stackcollapse-callgrind.pl cg.out > out.folded
flamegraph.pl out.folded > fg.svgDTrace (macOS / FreeBSD / Solaris)
# CPU sampling
sudo dtrace -x ustackframes=100 \
-n 'profile-997 /execname=="prog"/ { @[ustack()] = count(); }' \
-o out.stacks \
sleep 30
stackcollapse.pl out.stacks > out.folded
flamegraph.pl out.folded > fg.svg
# Kernel + user combined
sudo dtrace -x stackframes=100 \
-n 'profile-997 { @[stack(),ustack()] = count(); }' \
-o out.stacks sleep 30Go pprof
go tool pprof -raw -output=cpu.pprof ./prog
stackcollapse-go.pl cpu.pprof > out.folded
flamegraph.pl out.folded > fg.svgJava (async-profiler)
# async-profiler: https://github.com/async-profiler/async-profiler
asprof -d 30 -f out.collapsed -t <PID>
# -f out.collapsed writes pre-collapsed format
flamegraph.pl out.collapsed > fg.svg
# Or use jstack periodically
for i in $(seq 1 100); do jstack <PID> >> jstacks.txt; sleep 0.1; done
stackcollapse-jstack.pl jstacks.txt > out.folded
flamegraph.pl out.folded > fg.svgRust (cargo-flamegraph)
cargo install flamegraph
# Runs perf internally and generates flamegraph.svg
cargo flamegraph --bin mybin---
flamegraph.pl options
flamegraph.pl [options] folded_input > output.svg| Option | Default | Effect |
|---|---|---|
--title "text" | "Flame Graph" | SVG title |
--subtitle "text" | none | Subtitle below title |
--width N | 1200 | Width in pixels |
--height N | 16 | Frame height in pixels |
--minwidth N | 0.1 | Min frame width % (hide smaller) |
--fonttype font | Verdana | Font family |
--fontsize N | 12 | Font size |
--countname name | "samples" | Label for count in tooltip |
--nametype "Name:" | "Function:" | Label for function name |
--colors palette | hot | Color palette (see below) |
--bgcolors color | — | Background color |
--cp | off | Consistent palette across SVGs |
--reverse | off | Reverse the stacks (icicle-like) |
--inverted | off | Icicle chart (root at top) |
--negate | off | Negate diff values (for difffolded) |
--factor N | 1 | Multiply all sample counts by N |
--hash | off | Deterministic color by function name |
--palette file | — | Save/load color palette file |
Color palettes
| Palette | Best for |
|---|---|
hot | Default; red/yellow for hotness |
cold | Blue tones |
mem | Memory profiling |
io | I/O profiling |
java | Java (color-codes JIT vs interpreted) |
js | JavaScript |
perl | Perl |
python | Python |
red / green / blue | Monochrome variants |
aqua | Aqua tones |
orange | Orange tones |
yellow | Yellow tones |
purple | Purple tones |
---
Differential flamegraphs
Compare two profiles: red = more time (regression), blue = less time (improvement).
# Collect two profiles
perf record -g -o before.data ./prog_old
perf script -i before.data | stackcollapse-perf.pl > before.folded
perf record -g -o after.data ./prog_new
perf script -i after.data | stackcollapse-perf.pl > after.folded
# Generate diff (positive = regression in 'after')
difffolded.pl before.folded after.folded | flamegraph.pl > diff.svg
# Invert: positive = improvement in 'after'
difffolded.pl -n after.folded before.folded | flamegraph.pl --negate > diff_inv.svgReading the diff:
- Saturated red: function took significantly more time in the new profile
- Saturated blue: function took significantly less time
- Pale colors: small change
- Gray/white: no change
- Frame only in one profile: appears fully colored (red or blue)
---
Alternative flamegraph tools
Speedscope (browser-based, interactive)
# Install
npm install -g speedscope
# Use
perf script | speedscope -
# Opens in browser with left-heavy / right-heavy / sandwich viewsFirefox Profiler
# Supports perf data via import at profiler.firefox.com
perf script -F +pid > profile.perf
# Upload to https://profiler.firefox.cominferno (Rust implementation, fast)
cargo install inferno
perf script | inferno-collapse-perf | inferno-flamegraph > fg.svgpprof (Go, supports flamegraphs)
go tool pprof -http=:8080 profile.pb.gz
# Flamegraph view available in the web UI---
Reading patterns quick reference
| Visual pattern | Interpretation | Action |
|---|---|---|
| Wide frame at top (leaf) | This function is where time is spent | Optimise the function body |
| Wide base, narrow towers | Lots of different callees | Reduce call overhead; cache; batch |
| Very tall stack | Deep recursion or call chain | Check for unnecessary depth; iterative rewrite |
| Plateau of tiny slivers | Many small functions all sharing time | Inlining might help; or algorithmic change |
| One wide frame dominating everything | Single bottleneck | Focus optimisation here first |
| Flat top with many small frames | Vectorisation / unrolled loop | Usually good; check if SIMD expected |
| Diff: red at base, blue at top | Bottleneck moved deeper | New hotspot introduced lower in call chain |
The actionable hotspot is always the widest frame that has no (or very narrow) children above it. That is where CPU time is actually consumed.