perf record: Sample a Program for Profiling
perf record samples a program at a fixed frequency and writes the samples to perf.data for later analysis.
Where perf stat gives totals, perf record captures where time is spent. Paired with call graphs it produces the data behind a flame graph.
What it does
perf record runs (or attaches to) a program and takes periodic stack samples, storing them in perf.data. With -g it records call graphs so you can see which call paths dominate CPU time.
Common usage
perf record -g ./my-program
# sample at 99 Hz to avoid lock-step artifacts
perf record -F 99 -g -- ./my-program
# profile an existing process for 30 seconds
perf record -F 99 -g -p 12345 -- sleep 30Options
| Flag | What it does |
|---|---|
| -g | Record call graphs (stack traces) |
| --call-graph dwarf | Use DWARF unwinding when frame pointers are missing |
| -F <hz> | Sampling frequency in Hz (e.g. 99 or 999) |
| -p <pid> | Attach to an existing process |
| -o <file> | Write to a named file instead of perf.data |
In CI
For readable stacks either compile with frame pointers (-fno-omit-frame-pointer) or use --call-graph dwarf. Feed the resulting perf.data straight into a flame graph. Sample at 99 Hz rather than round numbers to avoid aliasing with periodic workloads.
Common errors in CI
"perf_event_paranoid setting is 2" or "Permission denied" means the kernel blocks sampling; lower kernel.perf_event_paranoid on the host. "Kernel address maps ... kptr_restrict" warnings mean kernel symbols are hidden; user-space profiling still works. Missing or "[unknown]" frames come from omitted frame pointers; add --call-graph dwarf. In containers, perf usually needs --cap-add SYS_ADMIN or a relaxed seccomp profile.