The State of CI Caching 2026
Caching is the highest-leverage CI optimization and the one teams most often get wrong: this is where the hit rate, the wasted minutes, and the real payoff actually sit.
Executive summary
Caching is the highest-leverage CI optimization that teams most often get wrong. A cache that is configured but rarely hit gives all of the maintenance burden and none of the speed-up, and the default configurations many teams ship with leave a large share of installs re-running on every build. The discipline that separates a fast pipeline from a slow one is rarely a better cache backend; it is a better cache key.
This report measures the gap between cache-enabled and cache-effective. The recurring finding is that hit rate, not whether a cache exists, is what determines payoff. A 54 percent effective hit rate means nearly half of builds still pay the full install cost, and that uncached work is both the slowest and the most wasteful part of a typical pipeline. Teams that never measure their hit rate cannot tell the difference between a cache that saves them money and one that quietly stopped working months ago.
The fix is mostly about keys and scope. Stable, content-addressed cache keys, separating dependency caches from build-output caches, and streaming layer caches that restore in seconds turn a mediocre cache into a consistent one. Each of these is a configuration change rather than a code change, which is why caching has the best ratio of payoff to effort of any optimization a CI team can reach for.
There is a second half to the waste that caching alone cannot touch. A warm cache removes predictable, repeated work, but it does nothing for a registry timeout, an out-of-memory kill mid-install, or a network blip pulling a layer. Those transient failures still force a full re-run, and they re-pay every cost the cache was supposed to save. Caching and self-healing are complementary: one removes deterministic waste, the other removes mechanical failure.
The throughline for 2026 is that caching is not a solved problem so much as an unmeasured one. Most teams have a cache. Far fewer know its hit rate, fewer still have keyed it to the actual dependency manifest, and only a minority pair it with a runner layer that recovers the transient failures a cache cannot prevent. The teams that close all three gaps turn the slowest, most repetitive part of CI into its cheapest.
Effective hit rate across common CI cache configurations. · Source: Latchkey analysis (modeled)
Estimated split of dependency-install wall-clock on a partially cached pipeline. · Source: Latchkey analysis (modeled)
Email me the report
The full report is right here on this page, free. Want the link in your inbox to read later or share, plus new Latchkey reports as they drop? Drop your email and we will send it over.
Sent! Check your inbox for the report link.
No spam. Unsubscribe anytime.
A cache that exists is not a cache that hits
Many teams enable caching, see the green 'cache restored' line in their logs, and assume the win is banked. The reality is more uncomfortable: a default lockfile-keyed cache often lands near a 54 percent effective hit rate, which means nearly half of builds still pay the full install cost. The cache is present on every run; it is simply not serving content on every run, and the difference is invisible unless someone goes looking.
The reason this hides so well is that a single build never tells you anything. A miss looks like a slow build, and slow builds have a hundred plausible causes. Only the aggregate hit rate over hundreds of runs reveals that the cache is a coin flip rather than a guarantee. Teams that treat cache presence as the success metric are measuring the wrong thing entirely.
Measuring hit rate, not cache presence, is the first step, and it is one most teams skip. The chart below ranks effective hit rate across the common configurations, and the spread is the whole story: the same cache backend can deliver anywhere from a third of builds to nine in ten depending purely on how it is keyed and scoped. The backend is not the variable; the discipline is.
Cache-miss re-installs are the biggest single chunk of install time
On a partially cached pipeline, re-installing on a miss is the largest slice of install wall-clock, ahead of restore, resolution, and post-install scripts. That ordering matters because it tells you where the leverage is. The slowest thing your install step does is the work it does when the cache fails, and every percentage point of hit rate you recover deletes a chunk of that slowest work rather than trimming the fast steps around it.
The install-waste breakdown makes the asymmetry concrete. Cache restore and lockfile resolution are real costs, but they are bounded and predictable; a miss re-install is the open-ended one, because it pulls the entire dependency tree over the network and runs every post-install hook from cold. Optimizing restore speed shaves seconds. Eliminating misses shaves minutes.
This is why raising the hit rate is the highest-payoff move available, and why it is so often overlooked in favor of faster runners. A bigger runner makes a cold install finish sooner, but it still pays for the cold install. A better key makes the cold install not happen at all. As the install-wall-clock chart shows, the install step shrinks steadily as the cache improves, and almost all of that shrink comes from converting misses into hits.
- Miss re-install is the single largest slice of install wall-clock on a partially cached pipeline, ahead of restore and resolution.
- A faster runner shortens a cold install; a better key removes it. Only one of those scales.
- Each recovered percentage point of hit rate deletes the slowest step, not the fast ones, so payoff is non-linear.
Time spent in the install step as caching improves. · Source: Latchkey analysis (modeled)
Cache keys are where most hit rate is won or lost
Keying on a volatile value invalidates the cache too often, so it almost never hits; keying too broadly serves stale artifacts that no longer match the dependency tree, which is worse than a miss because it produces silent, hard-to-debug failures. The art of caching is finding the key that changes exactly when the cached content should change, and not one moment before.
Content-addressed keys derived from the actual dependency manifest push hit rate from the low fifties toward the high seventies. The mechanism is simple: when the key is a hash of the lockfile and the toolchain version, the cache invalidates precisely when dependencies change and stays warm across every run that did not touch them. A one-line application change that leaves the lockfile untouched gets a full cache hit, which is exactly the behavior teams assume they already have and usually do not.
Separating dependency caches from build-output caches is the other half of the discipline. Dependencies change on a different cadence than build artifacts, and folding them into one cache key means a change to either invalidates both. Splitting them keeps each cache stable for its own change rate, and the strategy-payoff comparison shows the split adding a clean increment of speed-up on top of content-addressed keying alone.
Relative install speed-up over an uncached baseline. · Source: Latchkey analysis (modeled)
Streaming layer caches change the restore economics
Classic caches operate on a download-then-unpack model: before any useful work can start, the runner pulls a full archive and expands it, so the restore itself becomes a cost that scales with the size of the cached content. For large dependency trees and fat container layers, that restore can rival the install it was meant to replace, which caps how much a traditional cache can ever save.
Streaming layer caches break that ceiling by restoring only what a build actually touches, on demand, rather than rehydrating the whole archive up front. The effect on the numbers is dramatic: effective hit rate pushes past 90 percent because partial restores succeed where a monolithic restore would have missed, and install wall-clock drops by more than half because the runner stops paying for content it never reads.
This is why streaming layer caches are the strategy with the best payoff in the benchmark, sitting at the top of both the hit-rate and the speed-up charts. They are also the closest caching comes to free: the speed-up requires no change to the application, the dependency tree, or the tests. It is purely a function of how the cache restores, which is exactly the kind of mechanical win a managed runner layer can deliver by default.
- Traditional caches pay a full download-and-unpack restore before work begins; that restore is itself a cost on large content.
- Streaming restores only the bytes a build touches, so partial hits succeed where a monolithic restore misses.
- The result is 90 percent-plus effective hit rate and more than half the install wall-clock removed, with no application change.
Caching and self-healing solve different halves of CI waste
Caching removes the predictable, repeated work: the dependency install that has not changed, the build output that is bit-for-bit identical to yesterday's. What it cannot do is fix a transient registry timeout, a network blip mid-fetch, or an out-of-memory kill partway through an install. Those failures are not cacheable; they are mechanical, and they need a clean retry, not a warm cache.
The two failure modes are easy to confuse because both end in a slow, expensive build, but the remedies are opposite. A miss is solved by a better key. A transient failure is solved by re-running the step on a fresh environment. A team that pours effort into cache keys while ignoring transient failures will still see builds blow up unpredictably, and a team that auto-retries everything while leaving the cache cold will still pay for repeated work on every green run.
Pairing a high-hit-rate cache with auto-healing runners covers both halves: the deterministic waste the cache removes, and the transient failures the self-heal layer recovers before they ever reach a pull request. On managed runners that provide both a streaming cache and automatic recovery, the slowest and the flakiest parts of CI are addressed by the same infrastructure, which is why the caching story and the reliability story increasingly point at the same place.
An unmeasured cache silently decays
A cache key that was perfect at the start of a project rots as the project grows. A new toolchain version, a refactored monorepo layout, a switched package manager: any of these can change what the key should hash without changing the key itself, and the result is a cache that quietly drifts from a 78 percent hit rate back toward the low fifties over months. Nobody notices, because no single build looks broken.
This is the strongest argument for treating hit rate as a tracked metric on the same footing as test coverage or build duration. A cache you measure tells you the moment its hit rate regresses, which is usually the moment a dependency-management change invalidated the key. A cache you do not measure tells you nothing until someone finally asks why the pipeline got slow, by which point months of wasted minutes have already been billed.
The operational discipline is small and the payoff is durable: emit the hit rate, alert on a regression, and revisit the key whenever the toolchain or repository structure changes. Teams that do this keep their caches near the top of the hit-rate chart for the life of the project. Teams that do not watch their carefully tuned cache slide back toward the default-key baseline without ever seeing it happen.
The compounding case for caching first
Of every CI optimization, dependency and build caching has the best ratio of payoff to effort, and it compounds with everything downstream. A pipeline that caches well has less work in it, which means right-sizing the runner is cheaper, the macOS and Windows legs have less to do, and moving steady-state load to managed runners buys cheaper minutes for a smaller bill. Caching is the lever you pull first because it shrinks the surface every other lever acts on.
The inverse mistake is common and expensive: teams jump straight to cheaper or bigger runners without fixing the cache, and end up buying cheaper minutes for work they never needed to repeat. The runner change feels like progress because the bill moves, but the pipeline is still re-installing the same dependencies on half its runs. The cache was the real problem, and it is still unsolved.
Sequenced correctly, caching is the foundation. It requires no application change, it returns wall-clock immediately, and it makes every subsequent optimization land on a leaner pipeline. The teams that internalize that treat the cache key as a first-class part of the pipeline and measure its hit rate the way they measure everything else that matters, because they have learned that a cache nobody watches is a cache that has already stopped working.
Recommendations
Measure effective hit rate, not cache presence
Emit the cache hit rate as a tracked metric and watch it the way you watch test coverage. A default lockfile-keyed cache often sits near 54 percent, meaning half your builds still pay full install cost, and you will never know it from a single run. Alert on a regression so a key that silently stops matching the dependency tree surfaces in days rather than months.
Key on the dependency manifest, not a volatile value
Derive cache keys from a hash of the actual lockfile and toolchain version so the cache invalidates exactly when dependencies change and stays warm on every run that did not touch them. This is the move that pushes hit rate from the low fifties into the high seventies, and it is pure configuration: no application code changes.
Split dependency caches from build-output caches
Dependencies and build artifacts change on different cadences, so folding them into one key means a change to either invalidates both. Keep them separate and each cache stays stable for its own change rate, which adds a clean increment of speed-up on top of content-addressed keying.
Adopt a streaming layer cache for large content
For fat dependency trees and container layers, a traditional download-then-unpack restore is itself a cost. A streaming cache that restores only what a build touches pushes effective hit rate past 90 percent and removes more than half the install wall-clock, with no change to the application or the tests.
Pair caching with self-healing for the transient half
A warm cache cannot fix a registry timeout or an out-of-memory kill mid-install; those need a clean retry on a fresh environment. Run caching alongside auto-healing runners so the deterministic waste and the mechanical failures are both removed, and a transient blip never re-bills the whole pipeline.
Outlook
Expect the gap between cache-enabled and cache-effective teams to keep widening through 2026. As pipelines and dependency trees grow, the cost of a mediocre hit rate grows with them, so the teams that measure and tune their caches pull steadily further ahead of the teams that merely enabled one. The optimization is not getting harder; the penalty for skipping it is getting larger.
The architectural direction is toward caches that are managed rather than hand-rolled. Streaming layer caches that restore in seconds, content-addressed keying handled by the platform, and hit-rate observability built in are converging into a runner layer that delivers a high hit rate by default rather than as a configuration achievement. That shift moves caching from something every team re-derives badly to something the infrastructure simply does well.
For most teams the practical takeaway is that caching does not need a project so much as a metric. Track the hit rate, key on the manifest, split the caches, and pair the whole thing with a layer that recovers transient failures. The slowest, most repetitive part of CI becomes its cheapest, and it stays that way because the number that proves it is finally on a dashboard someone watches.
Methodology
This report draws on Latchkey's analysis of aggregate cache behavior across representative pipelines, framed against public developer surveys and DORA delivery research. Figures labeled "modeled" are illustrative estimates from representative pipeline and cache configurations, not a primary survey. Hit-rate and timing figures assume a standard two-core Linux runner (Latchkey managed runner modeled at $0.0025/min, roughly 70 percent below hosted) and a typical dependency footprint, and will vary by ecosystem and cache backend. Figures labeled "modeled" are illustrative estimates derived from public pricing and typical pipeline shapes, not a primary survey; figures attributed to a named source reflect that source. Pricing reflects published rates at time of writing and should be verified against current provider pricing.
Sources
- DORA State of DevOps Report
- GitHub Actions - billing & pricing
- Stack Overflow Developer Survey
- GitHub - Octoverse