Buildprof
Buildprof is a profiler for software builds. It records every descendant process in a Linux build and turns the result into an interactive timeline you can explore in the browser.
It works below any individual build system, so the same view can include Cargo crates, Ninja jobs, compiler and linker invocations, shell scripts, code generators, file access, and arbitrary tools launched along the way.

Why use Buildprof?
Build tools generally explain only the work they manage themselves. Cargo
timings cannot break down an arbitrary build.rs script; Ninja cannot see
inside commands it launches; compiler traces describe one compiler invocation
rather than the build around it.
Buildprof follows the complete process tree instead. It lets you:
- see where wall-clock time went across the whole build;
- spot work which ran serially, overlapped, or started unexpectedly late;
- inspect full commands, working directories, lifetimes, and exit statuses;
- follow files from the process which produced them to processes which read them;
- use the same profiler with Make, Ninja, CMake, Meson, Cargo, Go, or wrapper scripts; and
- optionally add compiler-internal phases from Clang, LLD, and nightly Rust.
The recording is a Perfetto protobuf trace. The UI processes it locally in your browser and recordings can also be queried with Perfetto Trace Processor.
Quick start
Option 1: open a pre-recorded build
Nothing to install. Open the ripgrep release build in the browser.
Option 2: record your own build
On the Linux machine that runs the build:
|
When the build finishes, the recording is saved as output.buildprof and
opens in your browser at buildprof.lalitm.com.
Any build system works; see Build systems.
Nothing is ever uploaded. buildprof.lalitm.com only delivers the UI itself. Your browser fetches the recording from localhost and processes it entirely in the page; no trace data leaves your machine.
Install
Use whichever of these you already have (see the Releases page for more options):
|
Usage
Choose another output path or disable automatic opening when needed:
Open an existing recording later with:
Recordings contain command lines and filesystem paths. Review them before sending them to anyone.
Builds on a remote machine
Over SSH there is no browser to launch, so Buildprof prints the port forward to run from your own machine instead and waits for the browser to fetch the trace:
VS Code Remote and JetBrains Gateway forward the port automatically. The wait
gives up after ten minutes; adjust it with --wait <SECONDS>, where 0 waits
forever. Alternatively, copy the recording to any machine with Buildprof
installed and run buildprof open there; the macOS build exists for exactly
that.
Build systems
Buildprof follows the process tree, so it does not need to understand the build system. These are exercised by the conformance suite on every change:
- Make: compiles, archiving, linking, and renamed outputs.
- CMake with Ninja: the configure step and the Ninja build.
- Meson with Ninja: the setup step and the Ninja build.
- Cargo:
rustcinvocations and linking; nightly self-profile data with--compiler-traces. - Go: compile, assemble, and link.
Anything else that runs as a child process is recorded the same way: shell scripts, code generators, wrapper scripts, and tools launched by the build. Work handed to a daemon or a remote executor happens outside the process tree and is not visible; use local or no-daemon modes where a build system offers them.
Compiler details
Process timing is usually the right level for understanding a build. When a particular compiler or linker invocation needs a closer look, enable compiler tracing:
Buildprof currently imports Clang -ftime-trace, explicitly selected LLD
--time-trace, and nightly Rust self-profile data. These events appear as a
summary of active compiler threads with expandable per-thread phase tracks.
A build which invokes Clang through an absolute path currently bypasses compiler tracing. Buildprof will still record the compiler process, but its Clang and LLD internal phases will be absent.
Compiler tracing can also change compiler cache keys or turn cache hits into misses. Existing Rust compiler wrappers remain in the invocation chain, but cache preservation is not guaranteed in this mode.
How it works
On Linux, Buildprof launches the command under ptrace and follows process
creation, execution, and exit through the complete descendant tree. A seccomp
filter lets it stop only for the filesystem operations it records instead of
paying the cost of intercepting every system call.
The recorder writes a Perfetto protobuf trace directly. Perfetto provides the storage format, query engine, and core timeline interactions; Buildprof adds the build-specific view on top, including process ancestry, command types, concurrency, file relationships, and optional compiler timing data.
Because recording follows descendants, work delegated to an existing daemon, a remote executor, or another machine is outside the trace. Use local or no-daemon execution modes when a build system provides them.
Backwards compatibility
Before 1.0, the CLI and the UI move in lockstep at the minor version: a recording is meant to be viewed in a UI from the same 0.x series, and patch releases never change the trace format. Every UI version stays deployed under its own path, the CLI opens the one matching its version, and the UI links to the matching series when it is handed a recording from a different one, so nothing stops working, but the trace format may change between minor releases.
From 1.0 onward, the trace format is stable and compatibility is permanent: any recording opens in every later UI, and newer UIs simply add features on top of older recordings.
Self-hosting the UI
Each release attaches buildprof-ui-v<version>.tar.zst, the complete UI as
static files. Serve its contents from any web server and point the CLI at it:
Requirements
- Linux with a kernel or container configuration that permits tracing child
processes: Docker needs
--cap-add SYS_PTRACE,kernel.yama.ptrace_scopemust be below 3, and gVisor-style sandboxes cannot trace at all - Rust 1.91 or newer when installing from source
Development
See CONTRIBUTING.md for the layout and the UI workflow. Run the complete conformance suite in the Linux development container:
For a quick host-side check of formatting, lints, unit tests, and package contents:
License
Licensed under the Apache License, Version 2.0. See LICENSE and AUTHORS.