Cachix
Last updated: Sep 23, 2026
Rationale
Cachix is the hosted binary cache we use for Nix. Every derivation a job builds is pushed to our private cache, and every later job that needs the same derivation downloads it instead of building it again.
The main reasons why we chose it over other alternatives are:
- It is a hosted service built specifically for Nix. There is no cache server to operate, and the client is a single command that configures the cache and pushes new store paths as they appear.
- It serves cryptographically signed store paths. Our machines trust only the public keys of the caches we configure, so a path that was not signed by one of them is never substituted.
- It supports private caches with authentication tokens, letting us cache everything that is built in the monorepo without exposing it publicly.
- It integrates with GitLab CI and with the Batch jobs that run Nix, because it only needs the Nix configuration that our job templates and container images already carry.
- It works for both architectures our jobs run on, since a Nix store path is cached per system and our runners build on x86_64 and aarch64.
- Flakes integrate with it easily, which is one of the reasons we chose Nix Flakes over other environment managers.
Alternatives
As our CI evolved, so did our interest in a cache that is closer to the runners. Below are the approaches we have reviewed, ordered from most to least interesting based on our specific needs.
Local Nix store on a persistent runner
- Jobs would be split into a build stage that populates the local Nix store of a runner and an execution stage that reuses it, with the runner created on demand and kept alive for a while after going idle.
- It would remove the round trip to a remote cache and reduce data transfer costs.
- The cache would live only as long as the machine, so the first job after a cold start would build everything.
- It requires separating build and execution, which today happen in the same job.
Local Nix store on a persistent runner was last reviewed on Dec 1, 2025.
Pre-built container images per execution flow
- Each flow would run from an image that already contains everything it needs, removing the need for a cache at all.
- It fits production workloads such as Batch jobs, which already run from a purpose-built image.
- For development jobs, the team considers it too expensive in terms of complexity and maintainability.
Pre-built container images per execution flow was last reviewed on Dec 1, 2025.
Usage
We use Cachix for:
- Substituting the Nix derivations that every GitLab CI job needs, and pushing the ones each job builds, so no derivation is built twice across branches and runners.
- Substituting the Nix derivations that our Batch jobs and their container image need.
- Trusting the cache's public key in the Nix configuration of our CI container image, next to the public cache of the Nix project.
We do not use Cachix for:
- Caching container images, which we publish to Amazon ECR and Docker Hub.
- Caching package manager downloads such as pnpm stores, which GitLab CI caches in S3.