Skip to content
Latchkey

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

Terminal
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 30

Options

FlagWhat it does
-gRecord call graphs (stack traces)
--call-graph dwarfUse 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.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →