Kache has three parts: a compiler wrapper, a local store, and an optional daemon.
Build path
For an eligible compiler invocation, the wrapper:
- parses the compiler arguments and discovers inputs
- computes a BLAKE3 cache key
- checks the local store
- asks the daemon for an exact remote result after a local miss
- takes a per-key lock and checks locally again
- runs the compiler if the entry is still absent
- stores outputs as content-addressed blobs
- queues a remote upload when a writable remote is configured
The second local check prevents duplicate work when another process fills the same key while this process waits for the lock.
| Result | Compiler ran | Meaning |
|---|---|---|
local_hit | No | Entry was already in the local store |
prefetch_hit | No | Background prefetch had placed the entry locally |
remote_hit | No | Exact remote lookup downloaded the entry |
miss | Yes | The key and at least one output blob were new |
dup | Yes | The key was new but all output blobs already existed |
passthrough | Yes | Policy declined to cache the invocation |
A dup is compiled work. It often means two over-specific keys produced the same bytes.
Local store
The store contains:
index.db, a SQLite index of entries and their blobsstore/blobs/<prefix>/<hash>, the content-addressed output files- entry metadata under
store/<cache-key>/
Identical output bytes share one blob. Restores first try copy-on-write cloning. Unix can use a restricted hardlink fallback for immutable artifacts; other cases copy. Executables and loadable libraries are never hardlinked because later tools may mutate them.
See Deduplication for platform details.
Daemon
The daemon owns remote work and periodic maintenance:
- exact remote checks and downloads
- background uploads and durable upload replay
- speculative prefetch
- scheduled garbage collection
- monitor statistics that require live transfer state
The wrapper connects through <runtime_dir>/daemon.sock on Unix or a named pipe on Windows. A daemon failure does not break compilation: local caching continues and remote work is skipped or deferred.
See Daemon overview and Lifecycle.
Interception boundary
As RUSTC_WRAPPER, Kache sees rustc and workspace-wrapper invocations. It does not wrap Cargo itself or arbitrary tools. Rust link work driven by rustc can be cached when the artifact policy allows it; an independently invoked linker is outside this path.
C/C++ caching is separate. Kache must be invoked as the compiler wrapper or through a compiler-name shim, and currently caches supported object compilations locally.
Planner
Without a planner service, the daemon can prefetch from manifests, Cargo metadata, remote indexes, and local history. With cache.planner.endpoint or KACHE_PLANNER_ENDPOINT, it first asks the preview planner for ranked candidates. A fallback response returns the client to its local planning path.
The planner does not affect local correctness or exact-key lookup. See Remote service.