kache 0.23.0

Zero-copy, content-addressed build cache for Rust, C/C++ and more, with S3 and shared-filesystem remotes.
---
title: Kache or sccache?
description: Choose a compiler cache based on the workflow you need
---

Kache and [sccache](https://github.com/mozilla/sccache#readme) both avoid repeated compiler work. This page explains the differences for teams moving to Kache or deciding whether it covers their build today.

This page describes the current projects; it does not claim that one cache is universally faster. Test the same repository, toolchain, runner, and remote before deciding.

## Main differences

| Question | Kache | sccache |
| --- | --- | --- |
| Primary workflow | Local-first cache with optional explicit remote synchronization | Client-server compiler cache with local and remote storage |
| Rust setup | `kache init` | `RUSTC_WRAPPER=sccache` |
| C/C++ setup | PATH compiler-name shims (`kache install-shims`) or `CC="kache cc"` | Prefix wrapper (`sccache gcc`); no ccache-style PATH farm |
| Remote backends | S3-compatible storage and filesystem paths | S3, Redis, Memcached, GCS, Azure, GitHub Actions, WebDAV, and others listed by sccache |
| Inspection | `monitor`, `stats`, `why-miss`, `report`, `list`, and `doctor` | `--show-stats`, logs, and server commands |
| Remote transfer | On-demand restore plus `sync`, manifests, and prefetch | Remote access is part of normal server operation |
| Rust executables | Cacheable by default on Linux and macOS | Rust crates that invoke the system linker are not cached, according to the sccache README |
| Incremental Rust builds | Kache disables or isolates incremental state according to its configured policy | Incrementally compiled Rust crates are not cached, according to the sccache README |
| Fallback | Hands work it does not cache to another wrapper, such as sccache | No Kache-specific handoff needed |

## Choose Kache when

- You want cache entries shared across local worktrees without a remote.
- You want to inspect individual events and ask why a compile missed.
- You want explicit pull, push, manifest, and prefetch controls for CI.
- Caching eligible Rust executable and linker outputs matters to your workload.
- You want one `PATH` change to cache Make/CMake/PKGBUILD object compiles without wrapping `CC` in a shell.

## Gaps sccache can fill

If you need a compiler Kache does not cache yet, [use sccache as a fallback](#use-sccache-as-a-fallback). Kache caches what it supports and passes the rest to sccache, so you do not have to choose one.

If a missing compiler, backend, or workflow still blocks you, [open a feature request](https://github.com/kunobi-ninja/kache/issues/new?template=feature_request.md). Include the build command and the compiler or backend. Concrete workloads help us prioritize support.

## Measure your own build

Compare cold, local-hit, and remote-hit cases separately. Keep these fixed:

- repository revision and lockfile
- compiler and linker versions
- target triple and build profile
- machine or CI runner class
- remote region and credentials

Run several samples after one warm-up and compare medians. A count-based hit rate does not show how much compile time was avoided, so record wall time as well.

Kache can generate benchmark artifacts with `kache report` and the repository benchmark harness. See [Benchmarks](/docs/benchmarks).

## Use sccache as a fallback

Put Kache in front of sccache. After `kache init`, add the fallback to your Kache config:

```toml title="~/.config/kache/config.toml"
[cache]
fallback = "sccache"
```

Kache still caches everything it supports. Compiler invocations it passes through go to sccache instead of the bare compiler. `KACHE_FALLBACK=sccache` sets the same option for a single build.

If the fallback fails to start or exits unsuccessfully, Kache warns and retries once
with the direct compiler. The direct compiler's result determines the build result.
Interrupts and termination requests (including shell statuses 130 and 143) do not trigger a retry.
Both attempts keep their diagnostics; the warning marks the transition to the direct
compiler. A genuine source error can therefore be reported twice.

On macOS, Kache also checks the output access of an identifiable local sccache TCP
server. A confirmed sandbox denial skips the fallback before compilation. This
optional check respects `SCCACHE_SERVER_PORT`; Unix sockets, unidentified servers,
and unavailable sandbox queries use normal fallback execution and failure recovery.
Kache does not start, stop, or change the server during this check. A server that
starts after the check can still inherit its launcher's sandbox, so recovery remains
necessary. Use `KACHE_FALLBACK=off` to disable the fallback for a build.

Build events and JSON report bypass details include `fallback_attempt` with the
wrapper, outcome, status, and diagnostic reason. The final `route` and `exit_code`
show whether direct compilation followed and whether it succeeded.

Invocations using standard input/output, preprocessor stdout, or an unexpanded
response file go directly to the compiler. This prevents a failed fallback from
consuming input or leaving partial stdout that cannot be replayed safely.