Filesystem setup
A filesystem remote stores the same versioned cache objects as S3 in a shared directory. It is useful when every builder can mount the same NFS, SMB, or other shared filesystem and no object-storage service is needed.
Minimal configuration
[cache.remote]
type = "filesystem"
path = "/mnt/shared-kache"
prefix = "artifacts"
Use an absolute path so the wrapper, daemon, and kache sync resolve the same
directory regardless of their working directory. Every machine that reads or
writes the remote must mount that directory and have suitable permissions.
Treat every writer to the shared directory as trusted. A filesystem remote is not a security boundary: a peer that can replace cache paths or create symlinks can influence what other machines read or overwrite. Use S3 with access controls when writers are not mutually trusted.
kache currently compiles the s3 and filesystem remote types. Other
OpenDAL services are not included in the binary.
Atomic writes
Writes are staged in a temporary directory and atomically renamed into their
final location, so readers never observe a partially written pack or manifest.
By default, the staging directory is <path>/.kache-tmp.
Override it only when the default is unsuitable:
[cache.remote]
type = "filesystem"
path = "/mnt/shared-kache"
prefix = "artifacts"
atomic_write_dir = "/mnt/shared-kache/.staging"
atomic_write_dir and path must be on the same filesystem. The final
rename cannot be atomic across filesystems and will fail with a cross-device
error. In particular, do not use the machine's /tmp unless it is on the
same filesystem as the shared cache. kache checks this when it connects and
refuses the remote with an explicit message rather than failing every write.
It must also sit outside the object tree (<prefix>/v3/...); otherwise
in-progress staging files are listed as if they were cached objects. The
default <path>/.kache-tmp already satisfies both rules.
A shared cache directory that other users can write is a trust boundary. kache
verifies that each write resolves inside the configured path, so a symlink
planted under the cache cannot redirect writes elsewhere, and it rejects keys
whose components end in a dot or space (Windows strips those, which would make
two distinct keys collide). This is defense in depth: provision the directory
with restrictive permissions rather than relying on it.
Directory layout
With the minimal configuration, the shared directory contains:
/mnt/shared-kache/
├── .kache-tmp/
└── artifacts/
├── v3/
│ ├── manifests/{crate_name}/{cache_key}.json
│ └── packs/{crate_name}/{cache_key}.tar.zst
└── _manifests/
prefix keeps kache's objects in their own subtree. The logical layout and
kache sync behavior are the same for S3 and filesystem remotes. Filesystem
prefixes cannot contain : so the same config cannot become a Windows drive
path or alternate data stream.
Keep KACHE_CACHE_DIR on fast local storage for each machine. Only
cache.remote.path should point at the shared mount; the local store is not
safe to share between machines.