---
title: Quick start
description: Enable Kache and verify reuse between two worktrees
---
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.
<video src="https://raw.githubusercontent.com/kunobi-ninja/kache/main/assets/demo-36381adc.webm" aria-label="a second worktree of the same commit building from cache hits, then the build report" autoPlay loop muted playsInline controls />
## Enable Kache
[Install Kache](/docs/getting-started/installation), then run:
```bash
kache init
kache doctor
```
`kache init` configures Cargo's Rust wrapper and makes sure the background daemon is running. On Unix it also sets `HOST_CC` and `HOST_CXX` when unset, so Kache caches the C and C++ that build scripts compile, and offers Cargo and compiler shims with a `PATH` line for your zsh, bash or fish startup file, [test pacing](/docs/getting-started/configuration#test-runner), and a `build.rustdoc` setting for the `rustdoc` shim when you have none. It also offers a login service. It does not set `CC` or `CXX`. See [C and C++](/docs/getting-started/c-cpp) for native build setup.
`doctor` checks the wrapper configuration, conflicting wrappers, cache configuration, daemon access, and Cargo and compiler 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:
```bash
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:
```bash
(
set -e
cd "$kache_trial/first"
cargo build --locked --target-dir "$PWD/target"
)
```
Then build the same revision in the second worktree:
```bash
(
set -e
cd "$kache_trial/second"
KACHE_PROGRESS=hits cargo build --locked --target-dir "$PWD/target"
kache stats --full --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, so that Kache can restore them. Running Cargo again with an already populated target may 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 Not cached section before expecting every unit to hit.
The report covers the second tree's recorded events from the last 24 hours. To see only the latest build session:
```bash
kache stats --full --last-build --root "$kache_trial/second"
```
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](/docs/commands/reference#the-full-report) for the selection rules.
By default Kache also [seeds a new target directory](/docs/getting-started/configuration#new-checkouts) with the registry and git dependency units that another checkout built with the same `rustc` in the host `debug` profile. In this walkthrough the second worktree usually gets the first one's dependencies this way. Cargo finds them fresh and skips them, so the report counts them neither as hits nor as compiles, and most hits come from your workspace's own crates. To send every crate through the cache, run the second build with `KACHE_SEED_NEW_TARGETS=0`.
The report's Time saved row is compile work avoided: the summed compile time of the entries that hit, 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 explain --root "$kache_trial/second"`, or `kache explain <crate>` with a Rust crate name from the report. Without `--root`, `kache explain` explains the newest build on this machine, wherever it ran; `kache explain <crate>` uses that crate's latest recorded miss in any tree. When the second worktree has no earlier build of the crate and both builds ran with `[cache] explain_miss` on, it compares with the first worktree's build instead. Check the reported input changes and the [cache limits](/docs/how-it-works/limits).
## Save a report
```bash
kache stats --full --root "$kache_trial/second" --format markdown --output "$kache_trial/reuse.md"
```
Add `--last-build` to report only 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](https://kunobi.ninja/). 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:
```bash
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
```bash
kache init --check # print proposed changes only
kache init --no-service # configure Cargo without a login service
kache init --no-shell # leave shell startup files unchanged
kache init --yes # accept defaults without prompts
```
Init shows its plan and asks once before applying it, with a separate confirmation if another Cargo wrapper is set. It backs up existing files. Open a new terminal to activate C/C++ caching and test pacing; for C/C++ you can instead run the activation command it prints. `--check` shows the planned changes without prompts or modifications.
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](/docs/getting-started/mutation-testing).
For Rust documentation, follow the [rustdoc setup](/docs/getting-started/rustdoc); it requires unstable Cargo flags.
## Executables and incremental builds
Kache caches eligible Rust executables by default on Linux and macOS: binaries, test binaries and build scripts, which Cargo compiles as executables. The default is off on Windows because executable debug information still refers to an external PDB path, so all three compile without the cache there. 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, notices a Cargo unit you are editing (a build of it, then a miss in the same target where only its sources or dependencies changed) and gives it isolated incremental state. A `git pull`, a branch switch or a rebase counts as editing too, and so does a change in a local crate the unit depends on. The mode covers every package Cargo builds incrementally, by default the workspace members and path dependencies of a debug build, including a library you edit while running `cargo build -p app`.
Kache neither stores nor uploads what it compiles this way. It skips the cache for up to eight builds of the unit. After the eighth, or after 15 minutes without a build of the unit, it checks the cache first: a hit restores the cached result and drops the state, and a miss keeps compiling incrementally. Until then, switching back to a version the cache already holds compiles it incrementally instead of restoring it.
A compile error keeps the state, so the fix still compiles incrementally, as it does with plain Cargo. Kache discards the state when rustc crashes or reports a problem with its incremental files, and after an interrupted build. Use `KACHE_ADAPTIVE_INCREMENTAL=0` to turn the mode off or `KACHE_PRESERVE_INCREMENTAL=1` to force the incremental path for diagnostics. A CI job that keeps its target directory between runs should turn the mode off; see [CI setup](/docs/remote-cache/ci#ephemeral-and-persistent-runners).
## Temporarily disable caching
```bash
KACHE_DISABLED=1 cargo build
```
This keeps the wrapper in place but passes compiler work through.