deniz.in

Markets

Weather

Loading weather

· via Hacker News – Front Page (hnrss.org)

Open-source buildprof maps builds to process timelines and pins Bun's slow link on Full LTO

buildprof records every process a build launches and lays it out on one timeline. Its author used it to show that link-time optimization, not the language, dominated Bun's old Zig-era build times.

Open-source buildprof maps builds to process timelines and pins Bun's slow link on Full LTO

What buildprof does

A developer has released buildprof, an open-source tracing tool for Linux that shows where compile time actually goes. In a blog post on lalitm.com that reached the front page of Hacker News, the author explains that builds are often slow for fixable reasons — inadequate parallelism, duplicated work, dependency fetching or an oversized link step — rather than simply because there is a lot of code to compile.

The tool needs no integration with a specific build system. You prefix your existing command: buildprof -- make -j16, buildprof -- cargo build, buildprof -- ninja -C out/target, or even an arbitrary repository script. buildprof then records every process the command spawns, including nested subprocesses, and arranges them on a single timeline. Time runs left to right, bar width encodes duration, and children appear below the process that launched them.

Builds viewed as process trees

The key idea, according to the author, is that build systems describe work in incompatible terms — Cargo thinks in crates, Ninja in build edges, CMake generates instructions for yet another system — but from the operating system's perspective they all look like processes launching other processes. A Rust build might produce a chain such as cargo, rustc, cc, collect2 and finally ld.lld.

Visualizing at that layer has three payoffs: it works across build systems without custom hooks, it naturally captures custom scripts both above and below the build system, and by recording which files each process reads and writes it can expose dependencies between steps even when they cross build-system boundaries.

The Bun case study that motivated it

The project started with a tweet from Jarred Sumner, chief architect of the Bun JavaScript runtime, claiming Bun's new Rust build was more than five times faster on Linux than its old Zig build. That clashed with the author's experience, where Zig projects of similar complexity usually compiled faster.

To investigate, the author replayed the Linux x64 CI builds of Bun 1.3.14 and Bun 1.4.0 on a 6-core, 12-thread Linux VM, preserving build steps and their dependencies. The numbers roughly matched: Bun's reported CI medians were 30m06s for the Zig era versus 5m37s for Rust, and the single-machine replay produced 24m24s versus 5m40s.

One easily missed detail in the tweet: the Zig build used Full LTO while the Rust build used ThinLTO. Full LTO merges compilation units into a single large optimization job; ThinLTO keeps more separation so much of the work can run in parallel.

What the traces showed

Recording the Zig-era build immediately exposed a bottleneck: an ld.lld linker invocation ran alone at the very end for over sixteen minutes, roughly two-thirds of the whole build. A second recording with buildprof's --compiler-traces option, which folds in LLD's internal timing events, showed almost all of that time spent in LTO — the linker was running compiler passes, not just combining object files. The OptModule phase alone took just over ten minutes and includes the passes that generate machine code.

The Rust-era build, by contrast, linked in 2m24s with ThinLTO enabled. Switching the Zig build's own flags to ThinLTO cut the link by 3m40s in a paired comparison, but linking still took nearly thirteen minutes. The compiler trace pointed at functions with JSC in their names — JavaScriptCore, the engine Bun embeds — and the linker's inputs included WebKit libraries such as libJavaScriptCore.a. The author found Bun was not compiling these itself; it downloaded them from a separate WebKit build that also used Full LTO, whereas the Rust build consumed a newer WebKit revision whose build recipe selected ThinLTO.

Why it matters

The Bun episode is a useful caution against reading a headline speedup as a verdict on a language. According to the author's traces, the bulk of the gap traced to link-time optimization settings — both in Bun's own link and in prebuilt WebKit libraries it consumed — rather than to Zig compilation being inherently slow.

More broadly, buildprof gives any Linux developer with a slow build a way to see whether the problem is parallelism, repeated work, dependency downloads or a monster link step, without instrumenting each build tool separately. For teams whose CI runs tens of minutes, that visibility points directly at the change worth making.

  • #open-source
  • #build-tools
  • #profiling
  • #compilers
  • #bun

Related posts