This host proxies and caches crates from
crates.io. Point Cargo here to speed up
cargo build/cargo add and cut outbound traffic.
Replace mirror.example.com below with this server's actual
hostname.
Replace the default crates-io source with the mirror in
$CARGO_HOME/config.toml (usually
~/.cargo/config.toml).
[source.crates-io]
replace-with = "mirror"
[source.mirror]
registry = "sparse+https://mirror.example.com/index/"
# confirm it took
cargo config get source.crates-io
Scope the mirror to a single project and commit it, so every teammate and CI job resolves through the mirror automatically.
[source.crates-io]
replace-with = "mirror"
[source.mirror]
registry = "sparse+https://mirror.example.com/index/"
Cargo reads .cargo/config.toml from the
project directory upward, merging with (and overriding) the global one.
[registries.mirror]
token = "Bearer YOUR_TOKEN"
Never commit this file — it's local-only by default and excluded from version control.
export CARGO_REGISTRIES_MIRROR_TOKEN="Bearer YOUR_TOKEN"
No repo changes needed — Cargo config keys map to env vars, so you can set these directly in your pipeline.
export CARGO_SOURCE_CRATES_IO_REPLACE_WITH=mirror
export CARGO_SOURCE_MIRROR_REGISTRY="sparse+https://mirror.example.com/index/"
cargo config get source.crates-io
curl -s https://mirror.example.com/index/config.json
# fetch something and time it
time cargo add serde --dry-run
| Check | Expected result |
|---|---|
cargo config get source.crates-io | Shows replace-with = "mirror" |
GET /index/config.json | Returns the sparse index config — mirror is reachable |
| First fetch of a crate | Slower — cache miss, fetched from upstream and stored |
| Repeat fetch | Fast — served from local cache |
crates.io.
cargo publish still goes straight to the real registry —
this mirror only accelerates reads. Cargo.lock checksums
are still verified against the crate's recorded hash regardless of
which source served the bytes, so supply-chain integrity holds even
when pulling through the mirror.