This document is generated from docs/feature-matrix.yaml by ci/render_feature_matrix.py. To change a row, edit the YAML and re-run the renderer (uv run --with pyyaml python ci/render_feature_matrix.py). CI fails if this file is stale.
sccache claims are best-effort and sourced from the upstream README and docs at https://github.com/mozilla/sccache. When uncertain, a row is marked partial with a note rather than no.
| Feature | zccache | sccache | Notes | Evidence |
|---|
| C/C++ object caching | yes | yes | Core feature of both caches; per-translation-unit .o caching. | link |
| Link caching (artifact + sibling files) | yes | no | zccache snapshots the output dir before the linker, captures sibling .pdb/.wasm/.map/runtime DLLs, restores them on hit. | README.md#link-time-side-effects |
| Rust rustc caching (--emit=metadata, --emit=link, extern crate hashing) | yes | yes | Both wrap rustc. zccache adds extern-crate content hashing for cross-worktree sharing. | link |
| Emscripten (emcc / em++) | yes | no | zccache caches emcc/em++ end-to-end. sccache's README documents C/C++/Rust/CUDA but not Emscripten. | link |
| wasm-ld linking | yes | no | WebAssembly linking cached as part of zccache's link-caching path. | README.md#link-time-side-effects |
| CUDA / nvcc | no | yes | sccache supports CUDA caching; zccache does not yet (out of current scope). | link |
| MSVC cl.exe / link.exe | partial | yes | zccache parses MSVC-style args and supports clang-cl; native cl.exe/link.exe integration is partial. sccache has first-class MSVC support. | link |
| Multi-file compilation fast path | yes | no | clang++ -c a.cpp b.cpp c.cpp โ per-file parallel cache lookups, only misses go to the compiler. | README.md |
| Response file (.rsp) expansion | yes | partial | zccache fully expands nested response files. sccache passes them through but does not deeply normalize them. | README.md |
| Feature | zccache | sccache | Notes | Evidence |
|---|
| clang-tidy (static analysis results cached) | yes | no | Static analysis diagnostics cached per translation unit and replayed on hit. | README.md |
| include-what-you-use (IWYU) | yes | no | IWYU output cached and replayed per translation unit. | README.md |
| rustfmt | yes | no | zccache routes rustfmt; recursive invocations always run so changed child modules cannot hide behind unchanged crate-root markers, while explicit skip_children=true invocations can use content markers. sccache caches rustc only. | link |
| clippy | yes | no | zccache caches clippy lint output. sccache caches rustc but not the lint pass. | link |
| cargo check / cargo build | yes | yes | Both work as RUSTC_WRAPPER for cargo check/cargo build. | link |
| Feature | zccache | sccache | Notes | Evidence |
|---|
| Ninja (via CC / CXX launcher) | yes | yes | | link |
| CMake (CMAKE_C_COMPILER_LAUNCHER) | yes | yes | | link |
| Meson (native file) | yes | yes | | |
| Make | yes | yes | | |
| RUSTC_WRAPPER | yes | yes | | link |
| setuptools-rust / maturin / scikit-build-core | yes | yes | Both work via standard CC/CXX/RUSTC_WRAPPER env injection. | |
| Feature | zccache | sccache | Notes | Evidence |
|---|
| Persistent daemon with sub-ms IPC | yes | partial | zccache's daemon serves hits in ~1ms over a single IPC roundtrip. sccache has a server, but each call pays ~170ms (spawn + handshake + disk I/O). | README.md#why-is-zccache-so-much-faster-on-warm-hits |
| Single-roundtrip IPC (length-prefixed bincode) | yes | no | One length-prefixed bincode message per compile. sccache's protocol uses multiple subprocess invocations per call. | link |
| Safe hardlink delivery on hit | yes | no | Cache hits use a capability-driven reflink, protected-hardlink, or copy ladder. sccache copies bytes back over IPC. | README.md#why-is-zccache-so-much-faster-on-warm-hits |
| Reflink delivery (ReFS, btrfs/XFS, APFS) | yes | no | zccache probes volume-pair capabilities and prefers true block-level COW while preserving stored mtimes. | README.md#safe-filesystem-materialization |
| In-memory metadata cache (DashMap) | yes | no | File sizes, mtimes, and content hashes live in a lock-free DashMap. Cache key computation is a memory lookup. | README.md#why-is-zccache-so-much-faster-on-warm-hits |
| Filesystem watcher (notify-backed) | yes | no | Background notify watcher tracks file changes in real time, so the daemon already knows whether inputs are dirty before compile is invoked. | README.md#why-is-zccache-so-much-faster-on-warm-hits |
| Content-addressed artifact store | yes | yes | Both hash-key cache entries by input content. | link |
| Protocol versioning (wire-format bump policy) | yes | partial | zccache embeds PROTOCOL_VERSION in every IPC frame and bumps it on any wire-format change. sccache versions its server but the policy is less explicit. | link |
| Compile journal (JSONL diagnostics) | yes | no | Every compile is recorded as secret-safe JSONL for diagnostics and partial replay; exact replay requires an independently captured trusted environment. | docs/journal-schema.md |
| Session stats / per-build hit rates | yes | partial | sccache exposes lifetime --show-stats. zccache adds per-session/per-build hit rates over the daemon connection. | link |
| Crash dumper (CLI + daemon) | yes | no | zccache_core::crash::install captures structured crash dumps for both binaries. | docs/architecture/runtime.md |
| Feature | zccache | sccache | Notes | Evidence |
|---|
| ZCCACHE_PATH_REMAP=auto cross-worktree sharing | yes | no | One cache entry serves every worktree of the same repo. Hashes are computed against a canonical path; absolute paths are remapped on the fly. | README.md |
| C/C++ -ffile-prefix-map injection | yes | no | zccache injects -ffile-prefix-map automatically so debug info points at the canonical path, not the worktree path. | README.md |
| Rust --remap-path-prefix injection | yes | no | zccache injects --remap-path-prefix so rustc output is worktree-independent. | README.md |
| Strict path validation | yes | no | --strict-paths rejects cache entries with non-canonical paths instead of silently leaking worktree paths. | README.md |
| Feature | zccache | sccache | Notes | Evidence |
|---|
| Local filesystem | yes | yes | Default backend in both caches. | link |
| S3 | no | yes | zccache is local-first by design; remote backends are out of scope today. | link |
| Google Cloud Storage | no | yes | | link |
| Redis | no | yes | | link |
| Memcached | no | yes | | link |
| Azure Blob | no | yes | | link |
| GitHub Actions Cache (native API client) | yes | yes | Both can persist to the GitHub Actions cache (zccache via zccache-gha, sccache via SCCACHE_GHA_ENABLED). | link |
| Distributed scheduler / build farm | no | yes | sccache has a dist-server build farm. zccache focuses on local-first warm-hit latency and does not ship a distributed scheduler. | link |
| Feature | zccache | sccache | Notes | Evidence |
|---|
| Linux x86_64 | yes | yes | | |
| Linux aarch64 | yes | yes | | |
| macOS x86_64 | yes | yes | | |
| macOS arm64 (Apple Silicon) | yes | yes | | |
| Windows x86_64 | yes | yes | | |
| Windows arm64 | yes | partial | zccache ships native Windows arm64 wheels and binaries. sccache's release coverage of Windows arm64 is partial. | link |
| Windows Defender exclusion helper | yes | no | zccache defender-exclusions add excludes the cache root from Defender real-time scans, recovering minutes of wall-time on Windows. | README.md#windows-defender-exclusions |
| PyPI wheels | yes | no | zccache ships native wheels per-platform; PyPI is the distribution channel. sccache distributes via crates.io and GitHub releases. | link |
| crates.io publishing | yes | yes | Both publish to crates.io (zccache-cli / zccache-daemon / zccache-core vs sccache). | link |
| GitHub Action (composite) | yes | yes | zccache ships a composite action that replaces sccache-action + Swatinem/rust-cache. sccache is wired via mozilla-actions/sccache-action. | link |
| Target snapshot caching + zccache warm backfill | yes | no | zccache snapshots target/ and backfills the daemon cache on restore. sccache leaves target/ caching to Swatinem/rust-cache. | README.md |
| Feature | zccache | sccache | Notes | Evidence |
|---|
| Per-hit cost | yes | partial | zccache serves hits in ~1ms (in-memory lookup + hardlink). sccache pays ~170ms per call (spawn + hash + IPC + disk I/O). | README.md#why-is-zccache-so-much-faster-on-warm-hits |
| mtime preservation on hits | yes | partial | zccache preserves the cached artifact's mtime so cargo's incremental fingerprint doesn't invalidate downstream crates. | CLAUDE.md |
| Compiler child priority (auto-throttle at 95% CPU) | yes | no | zccache demotes compiler children when system CPU is saturated, keeping the host responsive during big rebuilds. | README.md |
| Feature | zccache | sccache | Notes | Evidence |
|---|
| Hardlink cache-poisoning prevention and detection | yes | partial | Read-only blobs, native-file-ID registry, mediated detach, and watcher-assisted suspect verification prevent silent poisoning. | README.md#safe-filesystem-materialization |