---
title: Overview
description: What the daemon does, when it matters, and when you can skip it.
---

# 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 S3 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 S3 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 S3 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.

**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.

<Callout type="info">
When a planner endpoint ([Remote service](/docs/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.
</Callout>

## 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 S3
- 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

```sh
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](/docs/daemon/lifecycle).
