kache 0.6.0

Zero-copy, content-addressed Rust build cache. No copies, no wasted disk — just hardlinks locally and S3 for sharing.
---
title: Quick start
description: Run kache init, watch a cold build populate the cache, then see the second build restore every artifact with zero-copy reflinks.
---

# Quick start

The fastest path is `kache init`. It edits `~/.cargo/config.toml` to set `rustc-wrapper = "kache"`, installs the background daemon as a login service, and starts it. The whole flow takes a few seconds and is idempotent — re-run it any time to repair configuration.

```sh
# interactive setup
kache init

# or accept all defaults non-interactively
kache init -y

# skip the login service if you'd rather start the daemon manually
kache init --no-service

# check what init would do without changing anything
kache init --check
```

After `kache init`, your next `cargo build` is already cached. The first run is a normal cold compile; the second run restores everything from kache's store with zero-copy reflinks (copy-on-write) where the filesystem supports it, and hardlink or copy otherwise.

![kache: cold build populates the store, then `cargo clean && cargo build` restores every artifact with zero-copy reflinks](https://raw.githubusercontent.com/kunobi-ninja/kache/main/assets/demo.gif)

## Verify the setup

```sh
kache doctor
```

`doctor` checks for a working `RUSTC_WRAPPER`, conflicting wrappers (e.g. sccache), config file problems, and daemon connectivity. Add `--fix` to apply automatic repairs. For store integrity, `--verify` walks the store and checks entries, blobs, and metadata; add `--checksums` to also recompute and verify blob content hashes (slower); `--repair` removes corrupted entries.

## Manual setup (without `kache init`)

If you'd rather wire things up yourself:

<Steps>
  <Step>
    **Set the wrapper for your current shell session**

    ```sh
    export RUSTC_WRAPPER=kache
    ```

    Or persist it in `~/.cargo/config.toml` so it applies to every project:

    ```toml title="~/.cargo/config.toml"
    [build]
    rustc-wrapper = "kache"
    ```

    The `~/.cargo/config.toml` approach is more convenient for daily use. The env var is handy for CI or when you want to test kache on a single project without changing global config.
  </Step>

  <Step>
    **Run a build**

    ```sh
    cargo build
    ```

    The first build runs normally — kache compiles each crate and stores the result. You'll see normal cargo output.
  </Step>

  <Step>
    **Run the build again**

    ```sh
    cargo clean && cargo build
    ```

    This time, kache restores every crate from the cache with zero-copy reflinks (hardlink or copy where the filesystem has no copy-on-write). Cargo should complete in seconds for a project with no source changes.
  </Step>

  <Step>
    **Open the monitor**

    ```sh
    kache monitor
    ```

    The TUI monitor opens and shows the Build tab with the events from the last run — each crate listed as a local hit or miss with timing. Press `q` to quit. (Running bare `kache` prints help; use `kache monitor` to open the dashboard.)
  </Step>
</Steps>

## How to tell it's working

kache can print a one-line summary to stderr per crate, off by default. Enable it with `KACHE_PROGRESS=1` (or `hits`) to show hits, or `KACHE_PROGRESS=verbose` (or `all`) to also show dups and misses:

```
[kache] serde: local hit (2ms, 1.2 MB)
[kache] tokio: local hit (3ms, 4.8 MB)
[kache] myapp: miss (1.4s, 892 KB)
```

The `miss` line only appears at `KACHE_PROGRESS=verbose`; at `KACHE_PROGRESS=1`/`hits` only hit lines are shown. For a live view, open the monitor instead with `kache monitor`.

You can also check the cache state directly:

```sh
kache list               # all cached crates, sorted by name
kache list serde         # details for a specific crate
kache stats              # one-shot summary (no UI)
```

## What kache does not cache

By default, kache skips user-facing executables — `bin` crates and `--test` harnesses — because these linked outputs are more expensive to restore correctly. Dynamic libraries (`dylib`, `cdylib`) and proc-macros stay cached regardless. Set `KACHE_CACHE_EXECUTABLES=1` or `cache_executables = true` in the config file to cache executables too.

Incremental compilation is automatically disabled when kache is active — kache strips the `-C incremental=...` flag from each rustc invocation (setting `CARGO_INCREMENTAL=0` would be too late, since cargo injects the flag before the wrapper runs). kache's artifact caching makes incremental redundant, and on macOS, APFS-related corruption can occur when both are active simultaneously.

## Disabling kache temporarily

```sh
KACHE_DISABLED=1 cargo build
```

Even when disabled, kache strips incremental flags to avoid the APFS issue on macOS.