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.
Install nixcache
Install the latest released binary:~/.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: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:
Configure Nix
Add these settings to your Nix configuration to route substitution through the proxy: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:
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:
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 nativenix copy:
-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:
require-sigs = true and retain any upstream public keys you use.
Isolate untrusted forks
Give fork jobs credentials with only namespace-scopedblobs read access. Trusted CI uses separate writer credentials and holds the private signing key. Support can help configure these permissions during early access.
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 tocache_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.
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.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.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.Configure Nix on the builder
Add a separate configuration file and include it from Keep the existing trusted public keys. Determinate also adds its own installer substituter; the default
nix.custom.conf, which the Determinate installer reserves for user settings:cache.nixos.org route now goes through the proxy.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.
Test the installation
Run a package on the builder. Nix uses the builder’s local proxy for substitution, which falls back to 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.
cache.nixos.org on a shared-cache miss: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.