Skip to main content
nixcache is a local HTTP binary-cache proxy backed by Namespace blobstorage. It combines a local disk cache with shared storage, so a fresh runner can reuse cached Nix outputs without landing on the machine that built them.
Nix caching is in early access. Contact support to set up a cache namespace and the credentials your workflows need.
The proxy supports Linux and macOS on amd64 and arm64. It works with an existing Nix installation and does not change where builds execute. You can also use it on a remote Nix builder; configure each machine that needs to substitute or publish outputs.

Install nixcache

Install the latest released binary:
The installer verifies the archive’s SHA-256 checksum and installs to ~/.local/bin/nixcache without sudo by default. It requires curl, tar, sed, awk, and either sha256sum or shasum. It does not install Nix, modify Nix configuration, or start the proxy.

Start the proxy

After cache access is enabled for your workspace, start the proxy:
The command starts a background process and returns once the listener is ready. It prints the listener address, PID, and log path. The default address is http://127.0.0.1:18765. The example prefers the Cache Volume at NSC_CACHE_PATH to reuse local downloads across jobs. Without a volume, it uses the OS user cache directory: ~/Library/Caches on macOS, or XDG_CACHE_HOME with a fallback to ~/.cache on Linux. The examples below reuse this cache_root variable. -cache_dir selects a dedicated local directory for cached archives and staged uploads. Without it, the proxy uses temporary storage that is removed on clean shutdown. Shared blobstorage remains available to other runners regardless of the local directory.

Authentication

On Namespace instances, nixcache automatically uses the instance’s credentials. On other machines, sign in with nsc login before starting the proxy:
The credentials must have access to the cache namespace.

Configure Nix

Add these settings to your Nix configuration to route substitution through the proxy:
Keep Nix’s standard cache.nixos.org-1 trusted public key. Public packages retain their original signatures, so no additional key is required for the default public fallback. For multi-user Nix, set these options in the daemon’s configuration, normally /etc/nix/nix.conf, and reload or restart the daemon as required by your Nix installation. The daemon must be able to reach the proxy’s loopback address. A proxy running inside a different container or network namespace is not reachable at the daemon’s 127.0.0.1. Use extra-substituters instead of substituters if you want to retain other configured caches. Keeping https://cache.nixos.org as a direct substituter lets Nix bypass the proxy, so those downloads may not populate the Namespace cache. After configuration, ordinary Nix commands use the cache:
Replace your-package with an output from your project. This example uses flakes and the nix command, which must be enabled in your Nix installation.

Public-cache fallback

By default, nixcache falls back to https://cache.nixos.org for entries missing from Namespace blobstorage. It downloads archives into the local cache using parallel byte ranges and serves available bytes to Nix before the full download completes. Choose how upstream entries are cached with -cache-upstream: For example, restrict a consumer to entries already available in Namespace:
Namespace credentials are never sent to the public upstream. Fallback happens only on a blobstorage not-found response. Authentication failures, throttling, and storage outages do not trigger public fallback. Namespace credentials are still required in local-only mode. In persist mode, the proxy publishes the archive before its original .narinfo metadata. It preserves Nix hashes and signatures, so no private signing key is needed to mirror public packages. Once publication finishes, another runner can fetch the entry from blobstorage even with fallback disabled. Publication is asynchronous and best-effort. Failures are logged without interrupting the read. If a job must populate shared storage, allow publication to finish before stopping the proxy: a fallback entry stored log for a .narinfo path confirms that its archive and metadata were published. Stopping the proxy cancels pending publication.

Publish your own builds

Trusted CI needs cache write access and a Nix private signing key. Follow the authentication instructions, then publish a built output and its dependencies using native nix copy:
Run the writer instead of the reader proxy on that machine, or assign separate loopback ports with -listen and update the URLs accordingly. Replace the signing-key path with a file provisioned by your CI secret manager. secret-key is a native Nix store URI setting. Nix reads the signing key locally; it is not sent to the proxy. No separate upload client is required. Consumers of your signed outputs must add the corresponding public key to their Nix configuration:
Replace the placeholder with your cache’s public signing key. Keep require-sigs = true and retain any upstream public keys you use.

Isolate untrusted forks

Give fork jobs credentials with only namespace-scoped blobs read access. Trusted CI uses separate writer credentials and holds the private signing key. Support can help configure these permissions during early access.
-cache-upstream=local-only disables automatic fallback publication, not writes. Blobstorage enforces access permissions. Any process that can reach the proxy can use its credential’s permissions, so never expose a writer proxy, writer credential, private signing key, or writable trusted cache directory to untrusted jobs.
Use a separate proxy and local cache directory for each trust boundary. Public signing keys can be shared with readers; private keys cannot.

Operation and troubleshooting

Background logs are written to cache_dir/cacheproxy.log when -cache_dir is set. Use -log_file to choose another location, or -foreground to run under a process supervisor and log to the terminal. Logs include HTTP access and download or publication failures. At startup, the proxy removes unfinished downloads and staged uploads while preserving completed local entries. Stop it with kill -TERM <printed-pid> during job cleanup. There is no local eviction policy yet: budget disk space for downloads and concurrent uploads, and remove old cache directories while the proxy is stopped. Local cache entries are partitioned by storage endpoint, namespace, upstream URL, and credential scope. Token rotation can cause cold local reads; a persistent directory does not guarantee a local hit across credential changes.

Remote builders

Namespace compute instances can also run as remote Nix builders using Nix’s distributed builds feature. Remote builders execute builds; nixcache stores and serves their outputs. You can use either independently or configure the cache on your remote builders as well. The following steps prepare an instance with Nix and nixcache installed. Enable cache access for the workspace first, as described under authentication.
1

Create a bare compute instance

Create a new compute instance with your SSH key:
You can use an existing SSH key or create a new one specifically for this purpose with ssh-keygen -t ed25519.Grab the instance ID from the output.
2

Install Nix on the remote instance

SSH into the instance and install Nix using the Determinate installer:
Bare instances run as root and do not require sudo. With --init none, the installer leaves the Nix daemon stopped and may report a missing daemon socket during its self-test. Start it after configuring the cache below.
3

Install and start nixcache on the builder

Run the following from your client. The quoted heredoc keeps the environment variables on the remote instance, so the cache directory belongs to the builder rather than your client:
This Linux example prefers the instance’s Cache Volume when available. The proxy uses the instance’s credentials and defaults to -cache-upstream=persist to publish public packages to shared storage.
4

Configure Nix on the builder

Add a separate configuration file and include it from nix.custom.conf, which the Determinate installer reserves for user settings:
Keep the existing trusted public keys. Determinate also adds its own installer substituter; the default cache.nixos.org route now goes through the proxy.
5

Start the Nix daemon

Start the daemon once on this fresh instance. Redirect its input and output so it remains running after SSH disconnects:
On an existing builder with a running daemon, restart that daemon after configuration changes instead of starting a second one.
6

Test the installation

Run a package on the builder. Nix uses the builder’s local proxy for substitution, which falls back to cache.nixos.org on a shared-cache miss:
If the package is already in the builder’s Nix store, Nix does not need to fetch it again. Check the proxy’s access logs to see which requests reached the cache.
Follow Nix’s distributed-build configuration to connect your client to this instance. Enable builders-use-substitutes = true on the client to let remote builders fetch available dependencies from their configured substituters instead of copying them from the client. The proxy must run on the builder: its 127.0.0.1 is separate from the client’s. Building an output does not automatically publish it. Use the signed publication instructions on the builder to share your own outputs with other machines.
Last modified on September 15, 2026