Daemon
The daemon is a background process that handles everything that shouldn't block the build. The wrapper process is on cargo's critical path — every millisecond it adds to a rustc invocation adds to your build time. Anything that involves network I/O or heavy computation goes to the daemon instead.
What the daemon handles
Upload queue. After a cache miss and successful compilation, the wrapper hands the daemon a reference to the freshly stored entry and returns immediately. The daemon reads it from the local store and uploads to the configured remote in the background. No build time is spent waiting for uploads.
Remote checks. Before compiling a crate that missed locally, the wrapper asks the daemon to check the remote for the artifact. The daemon downloads it if found, then signals the wrapper to restore from the local store.
Prefetch. At the start of a new build session, the wrapper detects that a build is beginning (via a timestamped marker file), runs cargo metadata to get the full dependency graph, and sends the daemon a prefetch hint with all crate names in topological order. The daemon prefetches them from the remote before cargo even asks for them, turning remote hits into local hits for the rest of the build.
The prefetch hint fires once per build session (with a 5-minute cooldown) to avoid redundant work across sequential cargo commands in CI — cargo check, cargo clippy, cargo test may all run within the same session window.
Prefetch is optional. Set KACHE_PREFETCH_ENABLED=0 or [cache] prefetch_enabled = false on a long-lived runner whose persistent local store is already warm. The daemon then skips manifest warming, build-start planning, direct prefetch requests, and remote key-cache population. Exact-key remote checks and background uploads remain enabled.
When prefetch is enabled, the fallback planner maintains a remote key index. KACHE_REMOTE_KEY_CACHE_REFRESH_SECS / cache.remote_key_cache_refresh_secs controls its refresh interval; 0 performs one initial population and disables periodic refreshes.
Garbage collection. The daemon runs a GC sweep immediately on startup and then every 6 hours — eviction, dedup, orphan-blob cleanup, and incremental-dir pruning — so the store stays bounded without blocking any build.
When a planner endpoint (Remote service) is configured, the daemon asks it first and prefetches its ranked candidates from prior builds — useful on cold runners where cargo metadata alone underprefetches. Otherwise it falls back to the metadata/local planner; nothing else is needed. The client support ships in the daemon today; the hosted planner service is still in preview.
When the daemon is optional
If you're using kache locally with no remote configured, you don't need the daemon. Local caching works entirely without it — the wrapper reads and writes the local store directly.
The daemon becomes necessary as soon as you configure a remote cache. Without it:
- New artifacts won't be uploaded to the remote
- The cache won't be checked before a local miss triggers compilation
- Prefetch won't run
You'll still get local cache hits from previous builds, but the remote is effectively inert.
Communication
The wrapper communicates with the daemon over a Unix socket at <cache_dir>/daemon.sock (e.g. ~/.cache/kache/daemon.sock on Linux, ~/Library/Caches/kache/daemon.sock on macOS; on Windows this becomes a named pipe). The cache dir can be overridden with KACHE_CACHE_DIR. RPC calls are synchronous from the wrapper's perspective but non-blocking — the remote check has a 3-second timeout, so even a hung daemon caps the added latency.
If the daemon is unreachable (not running, stale socket, or timeout), the wrapper silently skips the daemon — logging at debug level only on a connect/timeout error — and continues without it. The monitor shows daemon: offline in this state, but local cache data is still displayed.
Starting the daemon
kache daemon start # start in background, returns when ready
kache daemon # show status (service, running state, socket, log path, version)
kache daemon log # tail the daemon log
For persistent operation, install as a system service — see Lifecycle.