Skip to content
Getting Started

Build one committed revision in two temporary worktrees. Each gets a fresh target directory, while Kache shares compatible cached outputs between them. Your existing checkout and build outputs stay in place.

Enable Kache

Install Kache, then run:

kache init
kache doctor

init configures Cargo's Rust wrapper and, when unset, HOST_CC / HOST_CXX for build-script C and C++. It also offers Unix compiler-name shims and a login service. It does not set CC, CXX, or PATH. See C and C++ for native build setup.

doctor checks the wrapper configuration, conflicting wrappers, cache configuration, daemon access, and compiler-name shims. Resolve any setup issues it reports before continuing.

Build in two worktrees

Use Bash, Zsh, or Git Bash at the root of a Rust repository with a committed Cargo.toml and Cargo.lock. The example builds HEAD; uncommitted changes stay in your original checkout. Complete any project-specific setup, such as initializing submodules, in each new worktree.

Run these blocks in the same shell:

kache_trial="$(mktemp -d)"
git worktree add --detach "$kache_trial/first" HEAD
git worktree add --detach "$kache_trial/second" HEAD

Build once to make eligible outputs available in the cache:

(
  set -e
  cd "$kache_trial/first"
  cargo build --locked --target-dir "$PWD/target"
)

Then build the same revision in the second worktree:

(
  set -e
  cd "$kache_trial/second"
  KACHE_PROGRESS=hits cargo build --locked --target-dir "$PWD/target"
  kache report --root "$PWD"
)

The explicit target paths keep the two builds separate even if you normally use a shared target directory. Cargo must request outputs for the second tree, giving Kache an opportunity to restore them. Running Cargo again with an already populated target can do no compiler work and produce no new Kache events.

Read the result

Look for cache hits and restored bytes in the second tree's report. The first build may also have hits if the store already contains compatible results. Some compiler invocations pass through; check the report's bypass reasons before expecting every unit to hit.

The report filters to the second tree's recorded events in the last 24 hours. On versions whose kache report --help lists --last-build, select just the latest recorded activity session:

kache report --last-build --root "$kache_trial/second"

--last-build was added after Kache 0.16.0. A session can include nearby or concurrent Cargo commands in one root; it is not an exact Cargo invocation ID. Only completed, retained compiler events appear. See the command reference for the selection rules.

Compiler work avoided is an aggregate estimate, not elapsed build time saved. This example demonstrates reuse; a speed comparison needs repeated measurements of the same workload. Rust hits also do not prove that C or C++ compilations were cached.

If the second build misses, run kache why-miss <crate> from that worktree, using a Rust crate name from the report. It compares the latest recorded key material for that crate. Check the reported input changes and the cache limits.

Save a report

kache report --root "$kache_trial/second" --format markdown --output "$kache_trial/reuse.md"

Add --last-build when your installed version supports it and you want the latest session. Open reuse.md before sharing it: reports include local paths and crate names, and store inventory covers the whole cache. The command writes a local file; publication is a separate action.

Kache is built by Kunobi. When sharing a result, link this walkthrough so someone else can reproduce it.

Keep the worktrees for further experiments, or remove them from your original repository when finished:

git worktree remove "$kache_trial/first"
git worktree remove "$kache_trial/second"

The report stays at $kache_trial/reuse.md. Git may refuse to remove a worktree with local changes; review those files before removing it.

Setup options

kache init --check       # print proposed changes only
kache init --no-service  # configure Cargo without a login service
kache init --no-shell    # leave terminal C/C++ setup unchanged
kache init --yes         # accept defaults without prompts

Init asks before editing Cargo or shell configuration and backs up existing files. If you enable C/C++ caching, open a new terminal afterward or run the activation command it prints. --check shows the planned changes without prompts or modifications.

To try the worktree example without persistent setup, skip kache init and prefix both cargo build commands with RUSTC_WRAPPER=kache. For example:

(
  set -e
  cd "$kache_trial/first"
  RUSTC_WRAPPER=kache cargo build --locked --target-dir "$PWD/target"
)

This enables the Rust wrapper for that command. C and C++ builds need their own wrapper configuration.

After setup, keep using ordinary Cargo commands. Give concurrent worktrees separate target directories. Tools that build in temporary copies, such as cargo-mutants, need no extra setup; see Mutation testing.

Executables and incremental builds

Kache caches eligible Rust executables by default on Linux and macOS. The default is off on Windows because executable debug information still refers to an external PDB path. Override the policy with KACHE_CACHE_EXECUTABLES or cache.cache_executables.

Normal artifact-cached builds strip Cargo's incremental directory argument. Adaptive incremental mode, enabled by default, learns rapidly changing Cargo units and temporarily gives them isolated incremental state. Use KACHE_ADAPTIVE_INCREMENTAL=0 to turn that off or KACHE_PRESERVE_INCREMENTAL=1 to force the incremental path for diagnostics.

Temporarily disable caching

KACHE_DISABLED=1 cargo build

This keeps the wrapper in place but passes compiler work through.

Available for:
Apple macOS logomacOSMicrosoft Windows logoWindowsLinux logoLinux
Download Kunobi