Kache resolves settings in this order:
- environment variable
- config file
- built-in default
KACHE_DISABLED, KACHE_CONFIG, KACHE_SOCKET_PATH, logging controls, progress controls, and credentials are operational settings. They do not all have TOML equivalents.
Config file
Open the editor:
kache config
Or edit TOML directly. Kache chooses the first file in this order:
KACHE_CONFIG- the nearest
.kache.toml, walking up from the current directory $XDG_CONFIG_HOME/kache/config.tomlor~/.config/kache/config.toml
The editor covers common fields and preserves advanced tables it does not expose.
[cache]
local_max_size = "50GiB"
cache_executables = true
[cache.remote]
type = "s3"
bucket = "my-build-cache"
region = "us-east-1"
Use type = "filesystem" with path = "/mnt/kache" for a shared filesystem remote. Only s3 and filesystem are compiled remote backends.
Core settings
| Environment | TOML key | Default | Purpose |
|---|---|---|---|
KACHE_CACHE_DIR | cache.local_store | OS cache directory | Persistent store |
KACHE_RUNTIME_DIR | cache.runtime_dir | local store | Socket, locks, logs, state, and session markers |
KACHE_SOCKET_PATH | none | <runtime_dir>/daemon.sock | Absolute daemon endpoint override |
KACHE_MAX_SIZE | cache.local_max_size | 50GiB | Registered blob bytes allowed before GC |
KACHE_AUTO_GC | cache.auto_gc | true | Spawn throttled background GC under size pressure |
KACHE_GC_MAX_AGE_HOURS | cache.gc_max_age_hours | 0 | Automatic age retention; 0 disables it |
KACHE_MIN_STORE_COMPILE_MS | cache.min_store_compile_ms | 0 | Skip local retention for faster compiles; 0 stores all eligible results |
KACHE_COMPRESSION_LEVEL | cache.compression_level | 3 | Zstd level, clamped to 1 through 22 |
| none | cache.event_log_max_size | 10MiB | Rotate the event log after this size |
| none | cache.event_log_keep_lines | 1000 | Lines retained when the event log rotates |
KACHE_DISABLED | none | false | Pass all compiler work through when set to 1 or true |
KACHE_LOCAL_ONLY | cache.local_only | false | Ignore all remote and planner configuration while keeping local caching |
KACHE_REMOTE_READONLY | cache.remote_readonly | false | Allow remote reads but suppress remote writes |
On macOS the default store is ~/Library/Caches/kache; on Linux it is $XDG_CACHE_HOME/kache or ~/.cache/kache; on Windows it is under %LOCALAPPDATA%.
Compiler policy
| Environment | TOML key | Default | Purpose |
|---|---|---|---|
KACHE_CACHE_EXECUTABLES | cache.cache_executables | Linux/macOS: true; Windows: false | Cache eligible Rust bins and test executables |
KACHE_CLEAN_INCREMENTAL | cache.clean_incremental | true | Remove tracked incremental directories during cleanup |
KACHE_ADAPTIVE_INCREMENTAL | cache.adaptive_incremental | true | Learn rapidly changing Cargo units and give them isolated incremental state |
KACHE_PRESERVE_INCREMENTAL | cache.preserve_incremental | false | Force eligible Cargo units onto isolated incremental state |
KACHE_INCREMENTAL_CRATES | cache.incremental_crates | [] | Force listed rustc crate names onto that incremental path |
KACHE_MODIFIED_INPUT_GUARD | cache.modified_input_guard | false | Do not store a result when a keyed input changed at or after build start |
KACHE_FALLBACK | cache.fallback | none | Wrapper used for ordinary Kache passthroughs |
| none | cache.exclude | [] | Source-path globs that bypass Kache |
| none | cache.bypass_crates | [] | Exact rustc crate names that bypass Kache |
| none | cache.bypass_argv | [] | Argument substrings that bypass Kache |
| none | cache.bypass_env | [] | NAME or NAME=VALUE rules that bypass Kache |
KACHE_CC_EXTRA_ALLOWLIST_FLAGS | cc.extra_allowlist_flags | [] | Exact C/C++ flag spellings accepted in addition to the built-in model |
Bypass rules can only reduce caching:
[cache]
exclude = ["vendor/problematic/**"]
bypass_crates = ["generated_bindings"]
bypass_argv = ["--cfg", "uncacheable_mode"]
bypass_env = ["SPECIAL_BUILD=1"]
Cache-key controls
| Environment | TOML key | Default | Purpose |
|---|---|---|---|
KACHE_KEY_SALT | cache.key_salt | none | Opaque value folded into every key |
KACHE_BASE_DIR | none | none | One extra path prefix normalized as <BASE_DIR> |
| none | paths.base_dirs | [] | Additional absolute prefixes with distinct stable sentinels |
KACHE_PATH_ONLY_ENV_VARS | cache.path_only_env_vars | [] | Path locator variables eligible for safe normalization |
KACHE_KEY_ENV_VARS | cache.key_env_vars | [] | Environment read by proc macros but not reported by rustc |
KACHE_VERIFY_RESTORES | none | off | Re-hash sampled or always before restoring |
Use a key salt when an unobserved toolchain component changes output:
[cache]
key_salt = "sysroot-2026-08"
Keep paths.base_dirs narrow. Normalizing unrelated roots to stable sentinels can make different inputs appear equal.
key_env_vars accepts exact names and trailing-star prefix patterns:
[cache]
key_env_vars = ["BOLTFFI_*"]
Values are hashed exactly and are not written to event logs. A changing value such as a job ID will destroy hit rate.
Hidden compile-time inputs
Some macros read files that rustc does not report. Put kache.toml without a leading dot next to the crate manifest:
extra_inputs = [
".sqlx/**/*.json",
"migrations/**/*.sql",
]
Matches are relative to that crate. Kache folds their paths and contents into its key and adds bounded watches to Cargo dep-info. Invalid or unreadable declarations fail closed.
For a workspace-root input used by a provider package and its direct consumers:
[[workspace.extra_inputs]]
crates = ["query-macros"]
inputs = [".sqlx/**/*.json"]
propagate_to_dependents = true
Workspace rules are accepted only from the .kache.toml beside the active Cargo workspace manifest. After adding a declaration to a target Cargo already considers fresh, rebuild that package once.
Remote settings
| Environment | TOML key | Default | Purpose |
|---|---|---|---|
| none | cache.remote.type | inferred as S3 for legacy config | s3 or filesystem |
KACHE_S3_BUCKET | cache.remote.bucket | none | S3 bucket |
KACHE_S3_ENDPOINT | cache.remote.endpoint | AWS | Custom S3-compatible endpoint |
KACHE_S3_REGION | cache.remote.region | us-east-1 | Region |
KACHE_S3_PREFIX | cache.remote.prefix | artifacts | Object prefix |
KACHE_S3_PROFILE | cache.remote.profile | credential-chain default | AWS profile |
KACHE_S3_USER_AGENT | cache.remote.user_agent | none | Custom HTTP User-Agent |
| none | cache.remote.path | none | Filesystem remote root |
| none | cache.remote.atomic_write_dir | <path>/.kache-tmp | Same-filesystem staging directory |
KACHE_S3_CONCURRENCY | cache.s3_concurrency | 16 | Concurrent operations for either backend |
KACHE_S3_POOL_IDLE_SECS | cache.s3_pool_idle_secs | 300 | S3 connection pool idle time |
KACHE_REMOTE_RESTORE_TIMEOUT_SECS | cache.remote_restore_timeout_secs | 300 | Daemon operation deadline; wrapper demand remains capped at three seconds |
KACHE_REMOTE_NEGATIVE_TTL_SECS | cache.remote_negative_ttl_secs | 60 | Cache definitive remote 404 results |
Credentials resolve from explicit KACHE_S3_ACCESS_KEY and KACHE_S3_SECRET_KEY, standard AWS variables, the selected AWS profile, web identity, container credentials, then instance credentials.
See S3 setup or filesystem setup.
Prefetch and planner
| Environment | TOML key | Default | Purpose |
|---|---|---|---|
KACHE_PREFETCH_ENABLED | cache.prefetch_enabled | true | Enable speculative manifest and planner prefetch |
KACHE_REMOTE_KEY_CACHE_REFRESH_SECS | cache.remote_key_cache_refresh_secs | 60 | Refresh the fallback planner's remote key index; 0 means initial load only |
KACHE_PREFETCH_MAX_KEYS | cache.prefetch_max_keys | 2000 | Entries allowed per plan; 0 is unlimited |
KACHE_PREFETCH_MAX_BYTES | cache.prefetch_max_bytes | 2GiB | Compressed bytes allowed per plan; in-flight downloads may finish |
KACHE_PREFETCH_DEADLINE_SECS | cache.prefetch_deadline_secs | 300 | Time during which a plan may start downloads; 0 disables the deadline |
KACHE_PLANNER_ENDPOINT | cache.planner.endpoint | none | Planner service URL |
KACHE_PLANNER_TIMEOUT_MS | cache.planner.timeout_ms | 750 | Planner request timeout |
KACHE_PLANNER_TOKEN | cache.planner.token | none | Bearer token |
KACHE_NAMESPACE | none | none | Shard namespace used by manifest upload and prefetch |
On a long-lived runner with a warm local store, speculative prefetch may be unnecessary:
[cache]
prefetch_enabled = false
Exact remote lookup and background upload continue to work.
Daemon, events, and diagnostics
| Environment | TOML key | Default | Purpose |
|---|---|---|---|
KACHE_DAEMON_IDLE_TIMEOUT | cache.daemon_idle_timeout_secs | 0 | Stop after idle seconds; 0 keeps it running |
KACHE_LOCAL_HIT_DAEMON | cache.local_hit_daemon | false | Experimental daemon-assisted local lookup with local fallback |
KACHE_HEARTBEAT_SECS | cache.heartbeat_secs | 30 | Event heartbeat cadence for long miss compiles; 0 disables it |
KACHE_EXPLAIN_MISS | cache.explain_miss | false | Record changed key groups on repeat misses |
KACHE_STORAGE_LAYOUT_ADVICE | cache.storage_layout_advice | true | Warn when storage layout forces copies |
KACHE_WINDOWS_HARDLINK | cache.windows_hardlink | false | Unsafe opt-in hardlink restores on non-CoW Windows volumes |
KACHE_PROGRESS | none | off | hits or verbose compiler progress |
KACHE_LOG | none | CLI: kache=warn; wrapper: off | Stderr tracing filter |
KACHE_LOG_FILE | none | CLI/daemon: kache=info; wrapper: off | File tracing filter and wrapper opt-in |
KACHE_EVENT_ROOT | none | detected | Root attached to events for report filtering |
KACHE_PAGER | none | platform pager | Pager command for kache list |
Pin file-backed settings
Set cache.ignore_env in a controlled project config to ignore environment overrides for settings that also exist in TOML:
[cache]
ignore_env = true
It does not suppress KACHE_DISABLED, KACHE_CONFIG, KACHE_SOCKET_PATH, credentials, logging, progress, or other environment-only controls. Kache warns when it ignores a set variable.
The daemon reads configuration at startup and watches the active config file. File changes trigger a graceful restart. Environment changes require starting a new daemon from that environment; an installed service uses its service definition, not your current shell.