Repository navigation
Description
EDIT: Workaround for now is to use cargo +nightly doc -Zrustdoc-mergeable-info, see #130676 for more info.
Reproduction Steps
- Checkout https://github.com/madsmtm/objc2/tree/815219f441c2f6a67a6787429e4460a43a66c7ff (don't forget to load git submodule
generated). - Run
cargo +nightly-2025-08-19 doc --workspace --target aarch64-apple-darwin. - Notice that it finishes in 1-2 minutes.
- Run
cargo +nightly-2025-08-20 doc --workspace --target aarch64-apple-darwin - You don't wanna wait for it to finish.
Logs from my CI on ubuntu-latest:
- On
nightly-2025-04-11(cargo doctakes ~2 mins) - On
nightly-2025-08-24(cargo doctakes ~24 mins)
Bisection
searched nightlies: from nightly-2025-08-19 to nightly-2025-08-20
regressed nightly: nightly-2025-08-20
searched commit range: 9eb4a26...05f5a58
regressed commit: 8365fcb
bisected with cargo-bisect-rustc v0.6.8
Host triple: aarch64-apple-darwin
Reproduce with:
cargo bisect-rustc --timeout 120 --start 2025-08-19 --end 2025-08-20 -- doc Additional Details
I'd guess this is probably from #144476, CC @notriddle @lolbinarycat @GuillaumeGomez. I see that the regression was spotted by the perf test suite, but probably not to the degree that I'm hitting.
I tried creating a more minimal reproducer for this, but that was kinda hard, since it's a performance thing, so it only really shows up in larger cases :/.
I did try looking at Activity Monitor, it looks like often there's only a single rustdoc process consuming CPU, and only intermittently, so there might be some global locking going on? fseventsd also seemed very active, but that might be normal, idk.
Activity
apiraino commentedon Oct 7, 2025
fmease commentedon Oct 7, 2025
54 remaining items
perf(ci): move `cargo doc` to separate nightly job with mergeable info
chore: add reference to rust-lang/rust#146895
perf(ci): move `cargo doc` to separate nightly job with `-Zrustdoc-me…
TennyZhuang commentedon May 11, 2026
I have a synthetic reproducer that appears to capture the large-workspace rustdoc/search-index regression shape from this issue, without depending on the full
objc2workspace.Caveat: this is a synthetic workload intended to stress cross-crate rustdoc search/index merging via many public items and cross-crate re-exports. It reproduces the measured regression shape locally, but maintainers should still validate whether it matches the real-workload behavior they care about.
Host triple:
aarch64-apple-darwin(macOS 26.4.1, Apple Silicon)Target triple:
aarch64-apple-darwin(default host target; no--targetflag was passed)Reproducer shape
Generator:
python3 gen_synth_ws_v2.py 100 100 synthetic-ws-largeWorkspace shape:
42pub usere-exports from all dependencies to increase search-index merge pressureAll measurements were clean builds using separate target directories.
Commands
Timings
9eb4a2652)05f5a58e8)ad3a598ca)-Zrustdoc-mergeable-infoad3a598ca)The
user / realratio drops from about 3.8x before the regression to about 1.2x after it, which is consistent with this issue's observation that the slow path appears much more serialized. This is an inference from/usr/bin/timeoutput, not direct process sampling.Artifacts
Public gist with the generator, rerun instructions, raw timing logs, and checksum manifest:
https://gist.github.com/TennyZhuang/cb57391783e5ef43aadcfc88faf84a93
MANIFEST.txtSHA-256:0c2583496d2fa0804d264c1c8feaaebca0955c00d567bc7ceb7dd9963f8045c0SimonSapin commentedon Jun 30, 2026
Documenting Servo (1839 crates) with rustdoc 1.95.0 on a fast 2026 laptop takes 62 minutes. Compiling takes 2.5 minutes.
taladar commentedon Jul 5, 2026
I am running into this on stable rustdoc 1.96.1 more and more too where documenting the whole workspace not only takes hours (many, many times more than compiling it does), it also seems to trigger entire rebuilds quite often despite me using a separate target dir for the doc run in my pre-commit hook. It might also be my imagination but it seems to take longer to do it all on an existing target dir than on a freshly deleted one (when it does decide to do all dependencies again).
egrieco commentedon Aug 2, 2026
Everyone is talking about large workspaces, but building local docs is also agonizingly slow on small projects. We're back to "I guess I'll go grab lunch/dinner while docs build."
It looks like there is progress on related issues. Definitely looking forward being able to use local docs once again. Currently local-first dev for Rust projects is non-viable.
taladar commentedon Aug 2, 2026
This seems to be mostly that issue nightly already has some options to fix where it regenerates the search index after every single crate, reading sometimes 100s of MB, adding the one crate, then writing it again. On nightly cargo docs there seem to be options to only do it once at the end.
GuillaumeGomez commentedon Aug 2, 2026
That's new. Do you have a repo so we can check?
ijackson commentedon Aug 4, 2026
I don't think it is new. The behaviour on stable is O(n^2) in the number of crates in the dependency stack, not the workspace, with large constants of proportionality.. Even a small crate will take a long time to do a from-scratch docs build if there are lots of dependencies.
Workspace size is relevant because in large workspace editing a lower-level crate can cause many rebuilds, and in that case the performance is O(size of workspace * total number of dependencies) which is also often unacceptable.
Trivial package with many dependencies, docs build time regresses 6x since 1.90.0
Test package
Cargo.tomlmain.rsDocs build time from clean tree with current stable on my Framework 13 AMD (not a slow machine):
Commands (rustc 1.97.1 (8bab26f 2026-07-14)):
Timing output
Docs build time in 1.90.0, before the regression
Docs build time with
-Z rustdoc-mergeable-infoThat's with 1.99.0-nightly (dc3f851 2026-07-26).
Conclusion
We should stabilise
rustdoc-mergeable-infomaking it the default.The primary use case for
cargo docis precisely local-first workfllows, where 1.91 onwards are afflicted by this critical perf regression. If there are bugs inrustdoc-mergeable-infothey're probalby preferable to the status quo.GuillaumeGomez commentedon Aug 4, 2026
So that's not a small project.
Thank you random person on the internet for telling us what is already written in this discussion multiple times and explaining us how to fix the situation even though we've been working on it for months.
egrieco commentedon Aug 4, 2026
Yes free-launch (repo). It's a little hobby project. I haven't pushed recent changes, but the version that is up (v0.2.9 02e1006) demonstrates this issue.
This tracks with the fact that the first ~300/1043 docs build very quickly while ~600+ start going slower and slower.
While 1043 total deps might seem big, there are only ~25 direct dependencies (a few could be eliminated). I'd consider this a small Rust project as opposed to something like Servo, which is truly large.
The bigger issue is that building docs shouldn't take this long. It seems like compiling should always take longer than building docs, but right now building docs takes ~10x longer than a full build:
Interestingly, the doc build lists 1043 units, while the actual build lists 598. I'm guessing that's due to disabled features being documented.
I do understand that the fix is in progress, and am grateful for the efforts of those working on the fixes. I think the frustration here is that this is a serious regression that occurred in
1.91and is still an issue in1.99. I'd tend to agree that:Please take all of the interest and discussion here from "random people on the internet 😃" in the best light. We're only keeping pressure on because of how important and useful Rust is to us all. We're grateful for all of the Rust team's work for an outstanding language and toolchain.
GuillaumeGomez commentedon Aug 4, 2026
Well, it's wrong. It means stabilizing new CLI options, and as we discovered in the recent weeks, it could be simplified greatly, and partially removed. Also, adding new CLI options means that
cargoneeds to be updated, but also all other build tools which use rustdoc. All this is a nightmare for both sides. For now, you can use the workaround provided in the first comment of this issue.Keeping pressure on a project (or on a team or an individual) is never a good idea. As much as you love Rust, this kind of behaviour only tends to create tension and frustration on both sides.
rust: Make `cargo doc` 17x faster
feat: split the 2 invocations into 2 runners, and skip dependancies (#…