Turn a perf Workload Trace into a Readable SVG Timechart
perf timechart gives you a timeline of what the system was doing during a workload. In this guide you will record a command, render its scheduler and CPU activity as output.svg, then repeat the capture with disk and network I/O when that is the detail you need. The examples use the installed linux-tools-common package, version 6.8.0-142.142, and the behaviour described by its local manpage dated 1 September 2026.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about 10 minutes for a first capture and inspection. You need the perf command, a workload you can safely repeat, and an SVG viewer such as a browser or Inkscape. Recording a command normally needs no elevated privilege. A system-wide capture may be restricted by the kernel or by local perf policy, so have an administrator available if the command reports a permissions failure.
1. Choose a bounded workload
Pick a command with a clear beginning and end. A bounded workload makes the chart easier to read and avoids collecting unrelated activity for an open-ended service. Replace the example with a command that is safe to run on your machine.
mkdir -p "$HOME/perf-timechart-run"
cd "$HOME/perf-timechart-run"
perf timechart record -- sh -c 'for n in 1 2 3 4 5; do sha256sum /usr/share/dict/words 2>/dev/null || true; done'
The workload is only an example. If that file does not exist, the loop still finishes, but it will not represent useful application work. Substitute a test command or a real repeatable operation. The -- separates perf's arguments from the command being measured, which prevents a workload option from being mistaken for a perf option.
Checkpoint
Recording should leave a perf.data file in the current directory and print a capture message. Check that without changing it:
ls -lh perf.data
2. Render the scheduler and CPU chart
Run the second form of the command with the trace as input. By default it reads perf.data and writes output.svg. The default capture contains scheduler and CPU events, including task switches, running time and CPU power states. It does not automatically become an I/O chart.
perf timechart --output=workload.svg
ls -lh workload.svg
Open workload.svg in an SVG-capable viewer. The message should say that a trace was written, followed by its duration. If the output file already exists, do not use --force casually: first decide whether the old chart is still needed. Select a new name, or move the old file to a dated archive. --force means that perf will not complain before proceeding; it is not a recovery mechanism for a wrong trace.
3. Capture I/O when waiting is the question
Repeat the workload with -I when you need disk or network activity. This option belongs to the record form, not the rendering form. Keep this capture separate so you can compare it with the scheduler-only run.
perf timechart record -I -- sh -c 'for n in 1 2 3 4 5; do sha256sum /usr/share/dict/words 2>/dev/null || true; done'
perf timechart --input=perf.data --output=io-workload.svg
ls -lh io-workload.svg
In I/O mode each activity bar has an incoming and outgoing part. Reads and ingress packets are shown above the bar; writes and egress packets are shown below it. The chart can also show time spent in poll, epoll or select system calls. A visually quiet chart is not proof that no I/O happened: very short events can be difficult to see at the chosen scale.
4. Make a crowded chart useful
Start with one filter rather than changing several settings at once. To show only a named task, use --process; the manpage allows a process name or PID. To draw only CPU power information, use --power-only. To omit processor state transitions, use --tasks-only. These options have meanings in both the record and render forms, but on recording they select what is collected, while on rendering they select what is drawn.
perf timechart --input=perf.data --output=worker.svg --process worker
perf timechart --input=perf.data --output=power.svg --power-only
perf timechart --input=perf.data --output=tasks.svg --tasks-only
Use --highlight=gcc to emphasise tasks with that name. A numeric value instead means a duration in nanoseconds, so a value such as 1000000 highlights tasks that run for more than one millisecond. Do not add a unit suffix to that highlighting value: the documented interpretation is numeric nanoseconds or a non-numeric task name.
For I/O charts, --io-min-time=5ms makes very short events draw as though they lasted at least five milliseconds. --io-merge-dist=10us merges events that are within ten microseconds of one another, reducing the number of figures in the SVG. These are display choices, not changes to the recorded events. Increasing them can make the picture clearer while hiding fine timing differences.
5. Adjust width and CPU ordering
The default SVG width is 1000. If labels overlap or the chart is being printed, choose a larger width. With --topology, CPUs are sorted according to topology rather than the default ordering.
perf timechart --input=perf.data --output=wide.svg --width=1800 --topology
If the chart contains too many tasks, --proc-num=20 asks perf to print task information for at least 20 tasks. This is a minimum, not a strict maximum, so it does not guarantee a chart with exactly 20 entries. Keep the original perf.data while experimenting: rendering options can be changed without recording the workload again.
6. Diagnose the common traps
If perf cannot record, first check that you are measuring the intended command and that the current directory is writable. A system-wide command such as perf timechart record has no workload after it, so it records the whole system until you stop it with the usual interrupt key. That can include unrelated users and services, and it may require elevated privileges. Use it only with a defined observation window.
sudo perf timechart record
# Stop the bounded observation with Ctrl-C, then render as root or copy perf.data safely.
sudo perf timechart --input=perf.data --output=system.svg
Do not run a privileged capture if the workload can be run unprivileged. The trace may contain system-wide activity and task names that should not be shared. Store it with appropriate permissions and remove it when the investigation is complete. If you only need a new chart, do not delete the trace: render it to a new filename instead.
If rendering reports that perf.data is absent, pass the actual path with --input=/path/to/perf.data. If symbols are not found, --symfs=<directory> tells perf to look for symbol files relative to that directory. Symbol lookup affects labels, not the basic existence of the trace. A trace recorded by a different system may also have different symbol files and task names.
Done means
- You recorded a bounded workload and confirmed that
perf.dataexists. - You rendered an SVG with an explicit filename and opened it in a viewer.
- You used
-Ifor I/O questions rather than assuming the default capture includes I/O. - You kept the original trace while testing filters, width and display thresholds.
- You know whether the capture was ordinary or system-wide, and have removed sensitive traces when they are no longer needed.