A few weeks ago the Rust corner of my feed lit up: a new toolchain promising dramatically faster builds, one benchmark, one headline number. I have seen this movie before: a number from somebody else's crate, somebody else's machine, and then a week of arguing about whether it applies to mine.
I did not want to argue about toolchains. I wanted a ruler: something that tells me, on my crate and my machine, where the seconds actually go (per crate, per build script, per link step), then tells me which fix is cheapest, and lets me verify the delta after I apply it.
So I built cargoscope. It measures. It recommends. It verifies. It never touches your toolchain.
The three commands
cargo cargoscope measure [--json out.json] shells out to cargo build --timings twice. The first build is timed; the second is a no-change rebuild. That second run is the trick: cargo omits fresh-skipped units from the timing report, so a build-script-run unit that still shows real duration in the no-change rebuild was genuinely executed again with no source changes. Its freshness is broken: typically a script that rewrites its own rerun-if-changed inputs. That is measured, not guessed from the script source.
The report shows wall time, top crates by compile time, build scripts that re-run on every build, and the codegen+link share of the final binary. On stable, the report is honest about what it cannot separate: "link step not separable on stable — the bin unit's duration covers codegen+link together."
cargo cargoscope recommend ranks fixes cheapest-first with exact config snippets: cargo check for the edit loop, fixing re-running build scripts, mold/lld linker, sccache, cranelift (gated behind --nightly-ok). It changes nothing. The snippets are yours to review and apply.
cargo cargoscope compare before.json after.json prints the measured delta and a verdict line. Only measured numbers; nothing is promised.
A real demo, honest numbers
The animated demo below is a real terminal recording on the repo's small fixture crate (verbatim transcript also in the repo). Watch the loop: measure flags a build script with RE-RUNS ON EVERY BUILD, recommend ranks the rerun-if-changed fix, I apply it, measure again, compare:
wall: 0.7s -> 0.7s (-6.6%) units: 5 -> 4 verdict: -6.6% wall time faster (0.7s -> 0.7s) Small crate, small numbers, no hype. The re-run flag is gone; the per-crate deltas are printed, wins and losses. That is the whole point: the tool's job is to make the second measurement possible, not to impress you with the first.
The bug the nightly CI caught
To separate the link step, cargoscope parses nightly -Ztime stderr. While dogfooding on a real nightly toolchain I found that rustc 1.101-nightly removed -Ztime entirely (unknown unstable option). The old code set RUSTFLAGS=-Ztime whenever it detected nightly, and cargo forwards RUSTFLAGS into its own internal rustc probe, so measure broke completely on new nightlies (cargo exit 101).
The fix: probe first (rustc -Ztime --print=sysroot; --version short-circuits before -Z validation, so it cannot be the probe), set the flag only when the probe passes, and fall back gracefully otherwise. A nightly CI job now runs measure on a real nightly toolchain every night and asserts the graceful fallback. Finding your tool broken on a toolchain you claimed to support is the best possible use of a nightly job.
Where the rivals beat us
Honesty section, as always with my tools:
- cargo-blaze wins if in-place recompilation fits your workflow: it actually makes rebuilds faster instead of measuring them. It is a young, invasive bet (replaces the compiler driver). cargoscope complements it: it can measure blaze's own delta.
-
cargo build --timingswins on zero install. The raw HTML timeline has everything cargoscope parses. cargoscope adds ranking, re-run detection, and before/after verification on top. -
cargo-bloatanswers a different question (binary size, not build time).
Honest limits
- It does not speed up your builds. It measures. If you want the build itself to go faster without measuring first, this is the wrong tool.
- Timing numbers are your machine's, your crate's, your profile's. A −6.6% here is not a claim about any other setup.
- Link-step timing needs a nightly toolchain whose rustc still accepts
-Ztime(removed by 1.101-nightly; support is probed, never assumed). -
cargo --timingsoutput format is not a stable API. The parser is defensive, records the tested cargo version, and fails loudly instead of guessing.
Try it
The npm package is not published yet, so install from source for now:
git clone https://github.com/techdevfun/cargoscope.git cd cargoscope && npm install && npm run build # then, inside any Rust crate: npx cargo-cargoscope measure Requires Node 20+ and a Rust toolchain (stable is fine). Zero runtime dependencies, MIT licensed.
Repo: github.com/techdevfun/cargoscope. Issues and PRs welcome; please include your measure output (redacted paths are fine) when reporting wrong numbers. Also listed in the TECHDEV catalog.




