Why Rust’s target/ directory gets so big
Multiple profiles, every dependency compiled per project, incremental artefacts and old build fingerprints — where the gigabytes go and which of them are safe to remove.
A Rust project's target/ passing several gigabytes is not a bug and not
misconfiguration. It is four things stacked on top of one another, each individually
sensible.
1. Every dependency is compiled, per project
Cargo does not have a shared machine-wide compiled-artefact cache the way Maven has
~/.m2. ~/.cargo/registry caches source; the compiled
.rlib files live in the project's own target/. Two projects
depending on the same version of the same crate compile it twice and store it twice.
2. Profiles multiply everything
target/debug and target/release are separate full trees. Add a
test profile, a bench profile, a --target for cross-compilation, and each is
another one. Debug builds are the large ones, because debug info is large.
3. Incremental compilation keeps state
target/debug/incremental holds the dependency graph and intermediate
products that let cargo rebuild only what changed. It grows with the number of distinct
builds you have done, and it is pure cache — deleting it costs one slower build.
4. Old artefacts are never collected
Cargo does not garbage-collect. Bump a dependency and the old version's compiled output
stays in target/ forever, alongside the new one. On a long-lived project this
is often the majority of the directory.
What to actually delete
The blunt instrument, which is also completely safe:
cargo clean
Nothing in target/ is authored by you and cargo build
regenerates all of it. The cost is a full cold rebuild.
The precise instrument, for point 4 specifically:
cargo install cargo-sweep
cargo sweep --time 30
cargo-sweep removes artefacts not touched in the last 30 days while keeping
the current ones, so you get most of the space back and keep an incremental build. If you
work in one large Rust repository, this is the right tool and this article can stop here.
Why it is off by default in dev-prune
dev-prune has a cargo adapter, and it is one of four that ship disabled — alongside Gradle, Maven and SwiftPM. The reason is a distinction worth making explicit.
Deleting node_modules costs a download, and usually a download from a warm
cache. Deleting target/ costs a compile, and a cold Rust compile of a
real dependency tree is minutes of CPU, not seconds of network. Both are recoverable; they
are not remotely the same price. A tool that treats them identically will eventually cost
you an afternoon in exchange for disk you were not short of.
So the four compiler-output adapters are opt-in, and when you enable them they get their own idle window — longer than the one used for dependency directories, because the threshold for "I will not miss this build" is further out than the threshold for "I will not miss this download":
devp config
That opens the settings screen, where adapters are grouped by language and can be
enabled, disabled, or given a per-adapter idle threshold — individually or a whole group at
once. When cargo is enabled, the verification before deletion is
cargo metadata --locked, which fails if Cargo.lock is out of date
with respect to Cargo.toml. If it fails, target/ stays.
Common questions
Why is my Rust target folder so large?
Four reasons compound: every dependency is compiled into each project rather than shared machine-wide, debug and release are separate full trees, incremental compilation keeps its own state, and cargo never garbage-collects artefacts from dependency versions you no longer use.
Is cargo clean safe?
Completely. Nothing in target/ is authored by you and cargo build regenerates all of it. The only cost is a full cold rebuild the next time you compile.
What is the difference between cargo clean and cargo sweep?
cargo clean deletes the whole target/ directory. cargo sweep --time 30 deletes only artefacts not touched in the last 30 days, so you keep a working incremental build while reclaiming the accumulated output of old dependency versions.