郭立 (leeguoo)

# Optimizing Computer Performance Overhead in AI Development · Rust Edition

When multiple agents develop in parallel, Rust repeatedly recompiling dependencies is often the biggest cost. Limit concurrency across two axes, share caches, isolate target directories, then pin the rules in AGENTS.md so your computer can handle three active lines of work at once.

Sep 1, 2026 · Posts · Public · Article

ON THIS PAGE

Rust: Don’t Let Multiple Worktrees Each Compile Everything Once

The biggest cost in parallel AI development is often not the model, but Rust repeatedly recompiling dependencies.

Scene: An 8-core Mac, two worktrees running cargo test at the same time. The problem is not “two cargo processes”; it is that each cargo process defaults to spawning compilers based on the number of logical cores. A dozen-plus rustc processes kick off together, the machine starts swapping like crazy, the compilation itself does not fail, but the computer is no longer usable for normal work.

Four moves. Do all of them.

1. Limit Concurrency: Two Axes, Both Required

Most people only limit half of it: they limit “how many cargo processes run at once” and forget that each cargo process can still fan out on its own.

  • sem limits how many cargo processes run at the same time
  • CARGO_BUILD_JOBS limits how many rustc processes each cargo process spawns. Without it, each cargo process runs with concurrency based on the number of logical cores — this is the real reason “2 cargo processes become 15 rustc processes.”

Wrapper (heavy-cargo):

$ sh
#!/bin/sh
# 8 cores / 16GB: one heavy cargo at a time, each cargo with at most two rustc processes.
# Tune based on swap, not just core count; with 32GB+, you can try sem -j 2.
exec sem --id rust-heavy -j 1 --fg -- \
  env RUSTC_WRAPPER=sccache CARGO_INCREMENTAL=0 CARGO_BUILD_JOBS=2 \
  nice -n 15 taskpolicy -b cargo "$@"

nice lowers CPU priority; taskpolicy -b sets Darwin’s background scheduling policy, throttling CPU/I/O for background tasks. The two are not strictly equivalent to Linux ionice; they are just platform-specific means toward the same goal.

2. Share the Compilation Cache (sccache)

sccache lets different worktrees reuse compilation artifacts. The key detail is incremental compilation:

  • Setting [env] CARGO_INCREMENTAL = "0" in .cargo/config.toml does not work[env] only passes variables to subprocesses started by cargo, which is too late to affect cargo’s own incremental compilation decisions.
  • But setting CARGO_INCREMENTAL=0 cargo … before startup does work; the wrapper above does exactly that. The benefit: disabling incremental compilation is limited to heavy builds, while other projects can keep using incremental compilation as usual. No global sacrifice required. If you do want to disable it globally, use [build] incremental = false.

Across worktrees, cache hits mainly come from third-party dependencies with the same registry and consistent paths. Your own crates by default will not hit across worktrees because absolute paths are part of the cache key — but newer sccache versions provide SCCACHE_BASEDIRS, which can normalize paths across different checkouts:

$ sh
SCCACHE_BASEDIRS="$PWD" RUSTC_WRAPPER=sccache CARGO_INCREMENTAL=0 cargo check

Do not promise 100% hits: crates such as bin, dylib, cdylib, and proc-macro invoke the linker and cannot be cached in the first place.

Always verify that it is actually working; otherwise, you will not know whether your setup is doing anything:

$ sh
sccache --zero-stats
heavy-cargo test -p server
sccache --show-stats     # Check cache hits / requests executed

3. Keep Each target Directory Separate; Do Not Share Them

Do not point multiple worktrees at the same CARGO_TARGET_DIR to save space — that creates lock contention and can make things slower. Reuse should come from the cache, not from a shared target directory.

4. Want Even More Speed? Validate Per Platform

  • Linker: On Linux, you can try mold / lld; the linking phase often eats half the time. Do not apply mold directly on macOS — mold’s Rust configuration explicitly limits it to target_os = "linux", and the Apple M1 test in the README runs Fedora Asahi, not macOS. Any linker change must be validated separately for the target platform.
  • Use cargo-nextest to run tests; set debug = "line-tables-only" in the dev profile to reduce debug info size.

Finally: Pin the Constraints in AGENTS.md

If the tools are installed but the agent still runs bare cargo test, your throttling has not actually landed. Write one rule explicitly:

$ text
Heavy Rust build/test must go through heavy-cargo;
agents must not directly start multiple cargo test processes concurrently.

In one sentence: limit concurrency across two axes, share caches, isolate target directories, and choose linkers per platform — then pin the rules in AGENTS.md. Only then can AI let you keep three lines of work open at once without crushing your computer.

next →
Networked Cross-Session: Let My AI Debug Directly with Your AI

Comments

Replies are public immediately and may be moderated for policy violations.

Max 1000 characters.