Repository navigation
Description
On our codebase (~1M LoC in a workspace with ~700 crates), we noticed a significant cargo target directory size regression after upgrading to Rust 1.97.1.
Examples of what we're observing:
cargo build --bins --releasewith default optimization settings (there are no[profile.release]section in our Cargo.toml) and latest mold linker: increase from ~6GB to ~7GB.cargo nextest archive(which as I understand simply builds everything with all features in debug profile), withCARGO_INCREMENTALenvironment variable set to1andRUSTFLAGSenvironment variable set to-C strip=debuginfoand necessary mold flags, and withdebug = 0in[profile.dev]: increase from ~62GB to ~79GB.cargo clippy --all-targetsorcargo clippy --binswithCARGO_INCREMENTAL=1and mold inRUSTFLAGS: no difference between 1.96.1 and 1.97.1 (at ~19GB and ~11GB respectively).
The results are very reproducible; just changing channel in rust-toolchain.toml between 1.96.1 and 1.97.1 (and cleaning cargo target directory so that it's empty) and re-running the command is enough to see the old or the new size. This also reproduces in a clean container based on rust:1.96.1-bookworm or rust:1.97.1-bookworm images (with regular libraries necessary for build installed from regular debian package repository).
Comparing two cargo target directories (for cargo nextest archive example) does not produce any insights; the directory structures are the same, and it's just that every file is suddely 20-50% larger on 1.97.1. debug directory is larger, everything in debug/deps is larger, and everything in debug/incremental/<crate_id>/<id> is larger (including dep-graph.bin and query-cache.bin).
Interestingly, archiving and compressing the target directory with ZSTD_CLEVEL=12 tar --zstd -cf ... produces archives of more or less the same size (~16.5GB), hinting that all that extra disk space used does not actually contain any significant amounts of new information; that the extra data is somewhat redundant from zstd point of view.
So I suspect that maybe this was caused by the change in #151994 . Maybe with the new mangling scheme, somehow our identifiers are so large (and there are so many of them in the output) that on non-incremental release builds they contribute 15% to the size of cargo target dir, and on incremental builds, 30%?
I'm sorry that this is not a very detailed or specific information.
Version it worked on
It most recently worked on: 1.96.1
Version with regression
rustc --version --verbose:
rustc 1.97.1 (8bab26f4f 2026-07-14)
binary: rustc
commit-hash: 8bab26f4f68e0e26f0bb7960be334d5b520ea452
commit-date: 2026-07-14
host: x86_64-unknown-linux-gnu
release: 1.97.1
LLVM version: 22.1.6
@rustbot modify labels: +regression-from-stable-to-stable -regression-untriaged
Activity
inga-lovinde commentedon Aug 6, 2026
After reading https://blog.rust-lang.org/2025/11/20/switching-to-v0-mangling-on-nightly/ , decided to try to enable
-C strip=symbols.Results:
-C strip=debuginfo: 62GB.-C strip=symbols: 53GB (9GB less).-C strip=debuginfo: 79GB.-C strip=symbols: 62GB (17GB less than without stripping symbols, but still 9GB more than on 1.96.1 with stripping symbols).apiraino commentedon Aug 11, 2026
Visited during compiler pre-triage: I wonder if there's anything else we can do to recover these binary size regressions caused by the new v0 mangling
@rustbot label i-compiler-nominated
apiraino commentedon Aug 13, 2026
Visited during triage on Zulip.
Currently we don't have other actionable for this than tuning
stripflag (as pointed out in the blog post), if you have any questions about passing them to cargo, let us know.We discussed how we could explore in the future other ways to strip symbols - that's open to anyone having bandwidth to tackle the problem - but nothing we can offer right now.
@rustbot label -i-compiler-nominated -i-prioritize +p-medium
inga-lovinde commentedon Aug 13, 2026
Not sure I understand; do you mean passing something even more aggressive than strip=symbols?
Just wanted to make it clear that the regression is there even with
-C strip=symbols(for incremental builds): 62GB on 1.97.1 vs 53GB on 1.96.1, or ~17% increase after upgrading to 1.97.1 (which is less than 30% increase after upgrading when only debuginfo is stripped, but still).(I understand that this problem is not actionable by the compiler team now.)
davidlattimore commentedon Aug 13, 2026
It makes sense that
strip=symbolswould only recover some of the size, since that option will strip the symbols from the final binary, but the symbol names still need to exist in the object files being passed to the linker, so still take up space in the target directory.With a non-stripped build, you can find the longest symbol name in your binary with a command like:
Most likely it'll be something with lots of generics and closures.
There was mention in the Zulip thread of the possibility of having an option to reduce symbol names to just hashes. A less drastic option might be to reduce the parts of the symbol name that represent closures to hashes.
inga-lovinde commentedon Aug 14, 2026
Yes, this was my assumption.
I'm running it on the .o files in target/debug/incremental, and for some of them get mostly generics (mostly diesel generics specifically, some of them 10k+ characters long), yes.
For other quite large .o files it's less interesting; for example, for one of them the longest symbol is just 542 characters (after
rustfilt), half of which is just a fully qualified name of a test method with a very verbose name nested deep in the module hierarchy.Still, perhaps (just as an idea for the far future) there could be another optional mangling scheme that instead of these full names only produces, say, their SHA-256 checksums, for scenarios in which it is important to make cargo target directory smaller (e.g. for building on systems with limited storage)?
But also that's just .o files. Around 70 to 80% of target/debug/incremental by weight is
depgraph.binandquery-cache.binandmetadata.rmetafiles, not.ofiles.bjorn3 commentedon Sep 15, 2026
The .rmeta files contains a list of all exported symbols. And the query cache might too.