Your GitHub Actions cache,
on your own hardware.
A drop-in replacement for GitHub's cache service, written in Rust. actions/cache, setup-* caches and BuildKit type=gha work unchanged on self-hosted and ephemeral runners.
Ephemeral runners
Cache server
Your storage
runner-7f3krunning jobrunner-2c9xrunning jobrunner-k41mrunning jobunknown clientno valid token
github-actions-cache-server- verify runner tokenOIDC
- scope to repo and branchisolated
- look up key34k/s, p99 7 ms
- save2.3 GiB/s
- restore7.9 GiB/s
29 MB image0.5 s start3 MiB idle
- local NVMe
- S3, RustFS, MinIO, R2
- Google Cloud Storage
- Azure Blob
- GitHub cache, self-hosted runner~20 MB/s reported54 s
- GitHub cache, GitHub-hosted runner~231 MB/s reported4.6 s
- This server, over 10 GbEline rate of the link0.86 s
- This server, same host7.9 GiB/s measured0.13 s
GitHub figures as reported by actuated (2023) and in google/wireit#239 (2022), your link and region decide the real number. Our method.
Two steps. Your workflows stay as they are.
1Run the server
docker-compose.yml services:cache-server:image: ghcr.io/falcondev-oss/github-actions-cache-serverports: ['3000:3000']environment:API_BASE_URL: http://cache-server:3000volumes: ['cache-data:/app/.data']volumes:cache-data:2Point your runners at it
runner # your runner, ARC scale set or containerimage: ghcr.io/falcondev-oss/actions-runnerenv:CUSTOM_ACTIONS_RESULTS_URL: http://cache-server:3000/The forked runner keeps your cache URL and skips self-update. Prefer the stock image? Use the one-line patch.
3There is no step 3
.github/workflows/ci.yml (unchanged) - uses: actions/setup-node@v6with:cache: npm- uses: actions/cache@v4with:path: ~/.cargokey: cargo-${{ hashFiles('Cargo.lock') }}
Why not a mounted volume?
A hostPath only helps tools you point at it, on one node, shared by every repository. The cache server speaks GitHub's protocol instead.
| GitHub cache | hostPath | This server | |
|---|---|---|---|
| Cache stored | GitHub cloud | one node | your server |
| Workflow changes | none | every workflow | none |
| actions/cache, setup-* | yes | no | yes |
| Ephemeral runners | yes | same node only | yes |
| Restore speed | ~20 MB/s | disk | LAN line rate |
| Per-repo isolation | yes | no | yes |
Works with what you already run.
Anything built on @actions/cache with the v2 cache service.
- Actions
actions/cacheactions/setup-nodeactions/setup-pythonactions/setup-goactions/setup-javadocker buildx type=ghaSwatinem/rust-cacheany @actions/cache tool- Storage
- FilesystemS3, RustFS, MinIO, R2Google Cloud StorageAzure Blob
- Database
- SQLitePostgreSQLMySQL
- Runs on
- DockerHelmARCamd64, arm64GHES
- Operations
- Prometheus /metricsLRU evictionself-healing cleanupmanagement API
Let your agent set it up.
Every page is plain Markdown for agents. Append .md to any URL, or send Accept: text/markdown.
Read https://gha-cache-server.falcondev.io/llms.txt and set up the GitHub Actions Cache Server for my self-hosted runners.Ship it in two minutes.
MIT licensed. Built by falconDev.