Open-source project
DeterminateSystems/magic-nix-cache-action avatar
DeterminateSystems/magic-nix-cache-action

magic-nix-cache-action: a free Nix binary cache for GitHub Actions

Save 30-50%+ of CI time without any effort or cost. Use Magic Nix Cache, a totally free and zero-configuration binary cache for Nix on GitHub Actions.

568 stars37 forksTypeScriptMIT

At a glance

What is it?
The Magic Nix Cache Action turns the GitHub Actions cache into a binary cache for Nix, so builds in one workflow run are reused in the next, with no extra service, no secrets and no configuration beyond adding a step. It is CI only, and the README is explicit about that boundary.
Who is it for?
Adopt magic-nix-cache-action if your GitHub Actions workflows build with Nix and you want the second run to be cheaper without running a cache service of your own. Do not adopt it if you need to share Nix builds with users outside CI, because the cache is not publicly available and the README points to a different product for that.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 15 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A cache that is the CI cache you already have

The pitch is in the first two lines: save 30-50%+ of CI time without any effort or cost, using Magic Nix Cache, a totally free and zero-configuration binary cache for Nix on GitHub Actions.

The mechanism is the part worth understanding. Magic Nix Cache uses the GitHub Actions built-in cache to share builds between workflow runs. Nix produces content-addressed store paths, and a binary cache is simply somewhere those paths can be fetched from. Instead of standing up a cache server, the action points Nix at a local daemon that reads and writes the GitHub Actions cache.

That design produces the five advantages the README lists. It is totally free, because it is backed by the GitHub Actions cache with no additional service to pay for. It is zero configuration, because you add the action and everything built in your workflow is cached. It needs no secrets, so forks and pull requests benefit from the cache too. It is secure, following the same semantics as the GitHub Actions cache, so malicious pull requests cannot pollute your project. And it is private, because the cache is stored in the GitHub Actions cache rather than with an additional third party.

The security claim is the one that matters most in a CI context, and the reasoning is that the action inherits the cache's own permission model rather than introducing a new trust boundary.

The primary language of the repository is TypeScript, the default branch is main, and the recent releases are v15 on 2026-09-09, v14 on 2026-05-29 and v13 on 2025-07-15.

Two steps in a workflow, in a specific order

The usage instruction is short and the ordering is not arbitrary.

yaml
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main

The action goes after the step that installs Nix, and the README says to add it in your workflow like this. That ordering is logical: the cache daemon can only be started once there is a Nix installation for it to serve.

The full example in the Usage section shows what a complete job looks like, and the permissions block is the detail worth copying rather than skipping.

yaml
name: CI

on:
  push:
  pull_request:

jobs:
  check:
    runs-on: ubuntu-latest
    permissions:
      id-token: "write"
      contents: "read"
    steps:
      - uses: actions/checkout@v6
      - uses: DeterminateSystems/nix-installer-action@main
      - uses: DeterminateSystems/magic-nix-cache-action@main
      - uses: DeterminateSystems/flake-checker-action@main
      - name: Run `nix build`
        run: nix build .

Two things stand out. The job asks for id-token write and contents read, which is the permission set the cache needs in order to read and write cache entries. And the job runs on pull_request as well as push, which is what makes the no-secrets claim meaningful, since a pull request from a fork gets a cache it did not have to be given a credential for.

The action supports Linux and macOS GitHub Actions workflows, and the sentence after the example is the summary of the whole feature: everything built in your workflow is cached.

The rate limit is the one failure mode you will meet

The Usage Notes section describes a single failure mode, and it is worth reading before you add the action rather than after you hit it.

The GitHub Actions Cache has a rate limit on reads and writes. Occasionally, large projects or large rebuilds may exceed those rate limits, and you will see evidence of that in your logs. The error looks like this.

code
error: unable to download 'http://127.0.0.1:37515/<...>': HTTP error 418
       response body:
       GitHub API error: API error (429 Too Many Requests): StructuredApiError { message: "Request was blocked due to exceeding usage of resource 'Count' in namespace ''." }

The behaviour on hitting it is the reassuring part. The caching daemon and Nix both handle this gracefully and will not cause your CI to fail. When the rate limit is exceeded while pulling dependencies, the workflow may perform more builds than usual, so you lose some of the time saving rather than the build. When the limit is exceeded while uploading to the cache, the remainder of those store paths is uploaded on the next run of the workflow.

The HTTP error 418 is unusual enough to be worth recognising, and the localhost port in the message is the daemon's own address, so the number is not something to file a bug about.

The upstream cache and what does not get stored

The Concepts section explains one piece of behaviour that would otherwise be surprising.

When you configure an upstream cache for the Magic Nix Cache, any store paths fetched from that source are not cached, because they are known to be fetchable on future workflow runs. The default upstream is https://cache.nixos.org, but you can set a different one.

yaml
- uses: DeterminateSystems/magic-nix-cache-action@main
  with:
    upstream-cache: https://my-binary-cache.com

The reasoning is about wasted space and wasted time. A path that already exists in cache.nixos.org will be there on the next run regardless of what the action does, so storing it in the Actions cache buys nothing and costs upload bandwidth against a rate limit that the README separately warns about. Excluding those paths keeps the cache to the things that are genuinely expensive to rebuild.

This also explains the structure of the action options table. There are options for the FlakeHub API server, the FlakeHub binary cache server and the FlakeHub flake name, alongside a listen address defaulting to 127.0.0.1:37515 and a startup-notification-port of 41239. The listen address matches the port in the error message above, which confirms that the daemon is a local process the action starts and points Nix at.

There are also diagnostic and source options. The diagnostic-endpoint is where diagnostics and performance data is sent, and setting it to an empty string disables that. The source options, source-binary, source-branch, source-pr, source-revision, source-tag and source-url, each conflict with all the other source options, and source-url overrides all of them, which is the escape hatch for pinning the cache binary to a specific build. The diff-store option controls whether the store is diffed before and after the action runs.

The boundary: no public cache, and an exit ramp

There are three limits, and the first one is the reason this tool is not a general Nix cache.

The first is that the Magic Nix Cache does not offer a publicly available cache, which means the cache is only usable in CI. The README's advice for anyone who wants to share Nix builds with users outside of CI is to use FlakeHub Cache instead. The options table already carries the FlakeHub server addresses, so the migration path is built in rather than bolted on, and there is a note offering one month free of FlakeHub Cache with a coupon code.

The second is the platform scope. The action applies to Linux and macOS GitHub Actions workflows. There is no Windows support mentioned, which is a real constraint for a Nix user on Windows who is running containers, since the Windows runner cannot use this cache at all.

The third is the dependency on the GitHub Actions cache itself. Everything the action does is mediated by that cache, so its rate limits, its retention policy and its availability are your constraints. A project that wants to control its own cache, serve builds to users, or work outside GitHub Actions needs a different tool.

On the licensing question there is a discrepancy worth flagging. The repository licence field shows MIT, while the package metadata in package.json declares LGPL for the package. The project is a distribution of a compiled action, and the code in src/ is TypeScript built with tsup and packaged with ncc, so if you are vendoring or redistributing the action rather than consuming it from the marketplace, read the LICENSE file and the package metadata together and decide which one governs the artefact you are shipping.

Editorial conclusion

Adopt magic-nix-cache-action if your GitHub Actions workflows build with Nix and you want the second run to be cheaper without running a cache service of your own. Do not adopt it if you need to share Nix builds with users outside CI, because the cache is not publicly available and the README points to a different product for that. Before you add it, note that it only covers Linux and macOS workflows, and that the last push was on 2026-10-08 with release v15 on 2026-09-09.

Frequently asked questions

How do I add the Magic Nix Cache to a GitHub Actions workflow?

Add the step after your Nix installation step, using DeterminateSystems/magic-nix-cache-action@main. The README's example puts it after DeterminateSystems/nix-installer-action@main and before the build step, and the job needs id-token write and contents read permissions.

Is the Magic Nix Cache free and does it need secrets?

Yes to both. It is backed by the GitHub Actions cache with no additional service to pay for, and because there are no secrets involved, forks and pull requests benefit from the cache as well.

What happens when the GitHub Actions cache rate limit is hit?

The caching daemon and Nix handle it gracefully and CI will not fail. Pulling dependencies may mean more builds than usual, and uploading the remainder of the store paths happens on the next workflow run. You will see an HTTP error 418 with a 429 Too Many Requests message in the logs.

Can I use the Magic Nix Cache outside of CI?

No. The cache is not publicly available, so it is only usable in CI, and the README points to FlakeHub Cache if you want to share Nix builds with users outside of CI.

What is the upstream-cache option for?

It sets the upstream cache the action fetches from, defaulting to https://cache.nixos.org. Store paths fetched from that upstream are not stored in the Actions cache, because they are already fetchable on future runs.

Official sources

  1. DeterminateSystems/magic-nix-cache-action on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/determinatesystems-magic-nix-cache-action.svg)](https://hysenlabs.com/projects/determinatesystems-magic-nix-cache-action)

Was this useful?