Home / Use cases / CI pipelines with warm caches
Continuous integrationCI pipelines with warm caches
Turn the second and third CI build of the day into near-no-ops by sharing a content-addressed cache across runs.
The problem
CI runs the same commit through the same toolchain with the same flags many times a day — per push, per PR, per merge. Stock ninja treats each run as cold and recompiles everything the runner did not keep. You pay for compute minutes recomputing artifacts that an earlier job already produced from identical inputs.
How rninja solves it
- ▸Run rninja in place of ninja in the CI image — the build step and flags are unchanged.
- ▸Enable the optional remote cache so the first job of the day warms a shared store and later jobs pull hits over async-nng.
- ▸Because hits are keyed on content, a green build on one runner seeds the cache for every other runner on the same inputs.
- ▸The scheduler still parallelizes the genuine misses, so cold sections of the graph do not become the new bottleneck.
// CI build step
$ export RNINJA_REMOTE_URL=tcp://cache.internal:5555 $ rninja -C out -j$(nproc) [cache] 812/842 actions served from remote ✓ build complete // mostly cached
- ·Remote cache is opt-in via RNINJA_REMOTE_URL and RNINJA_CACHE_MODE; leave it unset to use rninja purely locally.
- ·Use a side-by-side timing (time ninja target vs time rninja target) on your own repo before flipping it on across the fleet.
Questions
[+] Do I need to run a cache server?
A single small async-nng endpoint can serve many machines. It is opt-in — set RNINJA_REMOTE_URL to point at it, or leave it unset and rninja caches locally only.
[+] Can the cache produce a wrong build?
A hit only occurs when inputs, command line, and observed environment all match, so a hit is a guaranteed-equivalent artifact. On any mismatch rninja falls through and runs the real action.
Try it on this exact workload
Install rninja, point it at your existing build.ninja, and time it side by side. See the quickstart or browse other use cases.