1
0
Fork
You've already forked niks3
0
S3-backed Nix binary cache with garbage collection
  • Go 87.2%
  • Nix 12.1%
  • Shell 0.4%
  • PLpgSQL 0.3%
github-actions[bot] bdc918f7dc
Merge pull request #323 from Mic92/dependabot/go_modules/modernc.org/sqlite-1.48.0
build(deps): bump modernc.org/sqlite from 1.47.0 to 1.48.0
2026年03月30日 08:34:54 +00:00
.github ci: remove one-off repair-docker-tags workflow 2026年03月26日 01:27:51 +01:00
api feat: implement garbage collection task management 2026年03月25日 23:29:47 +01:00
bin release: handle version prefix more gracefully 2026年01月07日 23:07:26 +00:00
client Merge pull request #249 from philiptaron/socket 2026年03月26日 00:53:14 +01:00
cmd niks3-hook: fix default --db-path to match NixOS module 2026年03月26日 00:58:14 +01:00
cmdutil Replace fire-and-forget post-build-hook with persistent queue 2026年03月25日 23:41:45 +01:00
hook hook/worker: remove unused context parameter from drain() 2026年03月25日 23:42:59 +01:00
nix update vendorHash 2026年03月30日 08:30:52 +00:00
ratelimit client: add adaptive rate limiting for S3 and server requests 2026年02月06日 13:15:59 +01:00
server Merge pull request #249 from philiptaron/socket 2026年03月26日 00:53:14 +01:00
.envrc replace minio with rustfs 2025年12月09日 23:13:48 +01:00
.gitignore Split monolithic niks3 package into niks3, niks3-server, niks3-hook 2026年03月25日 23:42:58 +01:00
.golangci.yml linter fixes 2025年10月21日 14:06:27 +02:00
.goreleaser.yaml Replace fire-and-forget post-build-hook with persistent queue 2026年03月25日 23:41:45 +01:00
.mergify.yml add mergify 2024年10月27日 14:28:58 +01:00
.sqlfluff sqlfluff: disable for query.sql 2025年08月31日 21:31:58 +02:00
CONTRIBUTING.md README: extract docs to the wiki and contributing.md 2025年12月13日 10:27:52 +01:00
flake.lock Update flake input: nixpkgs 2026年03月30日 04:45:35 +00:00
flake.nix nixpkgs: switch to nixos-unstable-small 2026年02月06日 12:40:38 +01:00
go.mod build(deps): bump modernc.org/sqlite from 1.47.0 to 1.48.0 2026年03月30日 08:29:14 +00:00
go.sum build(deps): bump modernc.org/sqlite from 1.47.0 to 1.48.0 2026年03月30日 08:29:14 +00:00
LICENSE add MIT license 2025年11月06日 13:26:13 +01:00
README.md README: split architecture diagram into separate write/read/proxy flows 2026年03月26日 01:05:52 +01:00
sqlc.yml sqlc: fix schema path 2024年12月09日 11:02:02 +01:00

niks3 logo

S3-backed Nix binary cache with garbage collection

The idea is to have all reads be handled by the s3 cache (which itself can be high-available) and have a gc server that tracks all uploads to the cache and runs periodic garbage collection on s3 cache. Since writes to a binary cache are often not as critical as reads, we can vastly simplify the operational complexity of the GC server, i.e. only running one instance next to the CI infrastructure.

Architecture

Write path

flowchart LR
 niks3cli[niks3 CLI] -->|request upload| niks3[niks3 Server]
 niks3 -->|presigned S3 URLs| niks3cli
 niks3cli -->|PUT NAR + narinfo| s3[(S3 Bucket)]
 niks3 -->|track references| db[(PostgreSQL)]

The niks3 CLI requests an upload from the server, which returns pre-signed S3 URLs. The client uploads NAR files and narinfo directly to S3. The server tracks references in PostgreSQL for garbage collection.

Read path

flowchart LR
 nix[Nix Client] -->|read NAR + narinfo| s3[(S3 Bucket)]

Nix clients read directly from S3 (or a CDN in front of it) without going through niks3. This allows the read path to scale independently and remain highly available.

Read proxy (optional)

flowchart LR
 nix[Nix Client] -->|read request| niks3[niks3 Server]
 niks3 -->|fetch on behalf| s3[(S3 Bucket)]

For private S3 buckets, niks3 can proxy read requests from Nix clients to S3 using its own credentials. Enable with --enable-read-proxy. See the Private S3 Buckets wiki page.

Features

Binary Cache Protocol Support

niks3 implements the Nix binary cache specification with the following features:

  • NAR files (nar/): Compressed with zstd, stored in S3
  • Narinfo files (.narinfo): Metadata with cryptographic signatures
    • StorePath, URL, Compression, NarHash, NarSize
    • FileHash, FileSize (for compressed NAR)
    • References, Deriver
    • Signatures (Sig fields)
    • CA field for content-addressed derivations
  • Build logs (log/): Compressed build output storage
  • Realisation files (realisations/*.doi): For content-addressed derivations
  • Cache info (nix-cache-info): Automatic generation with WantMassQuery, Priority

Advanced Features

  • Cryptographic signing: NAR signatures using Ed25519 keys (compatible with nix key generate-secret)
  • Content-addressed derivations: Full CA support with realisation info
  • Multipart uploads: Efficient handling of large NARs (>100MB)
  • Transactional uploads: Atomic closure uploads with rollback on failure
  • Garbage collection: Reference-tracking GC with configurable retention
  • Parallel uploads: Client parallelizes NAR and metadata uploads

Operational Features

  • Authentication via API tokens (Bearer auth)
  • OIDC authentication for CI/CD systems (GitHub Actions, GitLab CI)
  • S3 credentials via static keys (--s3-access-key / --s3-secret-key) or IAM (--s3-use-iam for IRSA, EC2 instance profiles, ECS task roles)
  • Automatic upload via post-build-hook with crash-safe SQLite queue

Choosing an S3 Provider

niks3 works with any S3-compatible storage provider. We recommend Cloudflare R2 for most users due to zero egress fees and excellent performance.

For detailed pricing comparison and alternative providers, see the S3 Provider Comparison wiki page.

Setup

For complete setup instructions, see the Setup Guide in the wiki.

OIDC Authentication (CI/CD)

niks3 supports OIDC authentication for CI/CD systems. See the wiki for details:

Development

For development setup, database migrations, benchmarks, and contribution guidelines, see CONTRIBUTING.md.

Real-World Deployments

Need commercial support or customization?

For commercial support, please contact Mic92 at joerg@thalheim.io or reach out to Numtide.