The State of Monorepo CI 2026
In a big monorepo the only cheap build is the one you never run. Here is how the best teams skip the work.
Executive summary
The monorepo won the architecture debate for many large teams, but it changed the CI problem completely. In a polyrepo a pipeline naturally scopes to one service, because the repository boundary is the build boundary; in a monorepo a naive pipeline rebuilds and retests the entire graph on every push, and that cost grows with the repo, not with the change. The very thing that makes a monorepo good for developers, that everything lives together and changes atomically, is what makes its default CI ruinously expensive.
The whole discipline of modern monorepo CI is therefore about doing less. It is about detecting which targets a change actually affects, skipping everything else, and sharing a build cache so that work done once on any runner is never repeated. Nx, Turborepo, and Bazel are different answers to the same question of how to avoid rebuilding what did not change, and the choice between them matters far less than whether a team has committed to the principle at all. The principle is the win; the tool is an implementation detail.
This report quantifies the gap between full-graph and affected-only CI, how much a shared remote cache recovers, and why cache locality and fast runners matter more in a monorepo than almost anywhere else. The central finding is that the cost difference between a well-run and a poorly-run monorepo pipeline is not a few percent, it is nearly an order of magnitude, and the levers that close it are mechanical rather than fundamental.
Three figures frame the year. A naive full-graph build models at nearly nine times the CI minutes of an affected-only build in a large monorepo, which is the headline cost of skipping impact analysis. The overwhelming majority of targets in a typical pull request are genuinely unaffected and can be safely skipped, which is what makes impact analysis so effective. And a shared remote cache recovers a large fraction of monorepo CI minutes by ensuring that work done once on any runner is never repeated on another.
For engineering leaders the practical message is that monorepo CI cost is almost entirely self-inflicted and almost entirely fixable. The full-graph build is a choice, not a requirement, and the tools to do better are mature and widely adopted. A team that adopts affected-target detection, shares a remote cache kept close to its runners, and keeps its dependency graph accurate turns the monorepo from a CI liability back into the developer advantage it was supposed to be, and it does so without splitting the repo apart.
Modeled CI minutes for an average PR in a large monorepo under each strategy. · Source: Latchkey analysis (modeled)
Relative share of teams using each build/orchestration tool for monorepo CI. · Source: Synthesized from public developer surveys
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.
The full-graph build is the expensive mistake
The default monorepo pipeline rebuilds and retests everything, and its cost scales with the size of the repository rather than the size of the change. That is the single decision that turns a monorepo into a CI cost problem. A one-line change to a leaf package pays for a full validation of every other package, because the pipeline has no notion of what the change actually touched, so the bill grows with the codebase rather than with the diff and keeps growing as the repo does.
The savings chart shows the magnitude of the mistake. A full-graph build with no cache sits far above every other strategy, and moving to affected-targets-only collapses it by most of the way down, with local and remote caching taking it lower still. The gap between the top bar and the bottom is nearly an order of magnitude, which means this is not an optimization at the margins but the difference between a sustainable pipeline and an unsustainable one.
Affected-target detection inverts the relationship so cost scales with the change, and it is the highest-leverage change a monorepo team can make. Instead of asking "what is in the repo", the pipeline asks "what did this change affect", builds and tests only that, and skips the rest. That single inversion is what separates teams whose monorepo CI bill is proportional to their work from teams whose bill is proportional to their history.
- A full-graph build models at nearly 9x the CI minutes of an affected-only build in a large monorepo.
- Without impact analysis, a one-line change pays for a full-repository validation.
- Affected-target detection makes cost scale with the change instead of the codebase.
Most of a PR is genuinely unaffected
In a healthy monorepo the overwhelming majority of targets are not touched by an average pull request, which is precisely why impact analysis works so well. A change to one feature package leaves the other dozens of packages provably unchanged, so building and testing them is pure waste. The wasted-work chart shows where the avoidable minutes go, and rebuilding and re-testing unaffected targets together dominate it, far ahead of cache and cold-start overhead.
The risk in skipping work is correctness, and it is a real one: a skipped target must be provably unaffected, not merely assumed to be. This depends entirely on an accurate dependency graph, because the safety of the skip is only as good as the graph that decided the target was unaffected. A graph that misses an edge will skip a target that a change actually broke, and the regression ships green, which is the one failure mode impact analysis must never have.
This is where Nx, Turborepo, and Bazel earn their keep: they compute that dependency graph reliably rather than guessing. Each derives the affected set from the actual import and target relationships in the repo rather than from heuristics, which is what makes their skips safe. The value these tools provide is not the build orchestration itself but the trustworthy graph underneath it, because a trustworthy graph is the only thing that makes skipping work safe enough to do confidently.
- The large majority of targets in a typical PR are untouched and safe to skip.
- Rebuilding and re-testing unaffected targets are the two largest sources of avoidable minutes.
- A skipped target must be provably unaffected, which depends entirely on an accurate dependency graph.
Estimated split of avoidable CI minutes in a full-graph monorepo pipeline. · Source: Latchkey analysis (modeled)
A remote cache only helps if it is close
Skipping work depends on a cache hit, and a cache hit only saves time if fetching the cached artifact is faster than recomputing it. This is the subtlety that catches teams who add a remote cache and see less benefit than they expected: a remote cache pulled over a slow link can be slower than rebuilding small targets, so the cache that was supposed to save minutes adds them instead. The cache is not free; it trades computation for network transfer, and that trade only pays when the network is fast.
Cache locality is what makes the trade reliably favorable. When the artifact store sits near the runner, fetching a cached result is fast enough that it beats recomputation for almost any target, and the shared cache delivers the recovery it promises. When the store is far away, the calculus flips for small targets and the cache becomes a coin flip, which is exactly the inconsistency that makes teams distrust their cache and stop relying on it.
This is why cache locality matters more in a monorepo than almost anywhere else. A monorepo CI strategy is built on the assumption that cache hits are cheap, and that assumption only holds when the artifact store sits near the runner fleet. A remote cache that is shared across runners but physically distant undermines the whole strategy it was meant to support, which is why the fastest monorepo teams treat cache locality, not just cache existence, as a first-class concern.
Cost scales non-linearly with headcount
Because more engineers means more merges into the same graph, full-graph monorepo CI spend climbs faster than headcount. The cost chart shows the curve: a twenty-five-engineer team on a full-graph pipeline is manageable, but the same pipeline at a hundred engineers is several times more expensive, not four times, because more engineers produce more frequent merges that each trigger another full-graph build. The cost compounds where the merges compound.
Teams routinely cross from a manageable bill to an alarming one around the point where a platform group would otherwise pay for itself, which is not a coincidence. The same growth that makes a platform team viable is the growth that makes full-graph CI unsustainable, so the alarming bill and the dawning realization that the repo needs dedicated tooling tend to arrive together. The monorepo that was fine at twenty-five engineers becomes a budget problem at a hundred without anything obviously changing except scale.
Affected builds plus a shared cache flatten that curve, and managed runners take another large bite out of the per-minute rate underneath it. The chart's lowest bar combines all three: affected-only work, a shared cache, and managed runners, and it brings the hundred-engineer cost back down below where it started. The non-linear curve is not inevitable; it is what a full-graph pipeline does, and the combination of impact analysis, caching, and a cheaper runner rate bends it back toward linear.
Modeled monthly CI spend by engineer count, full-graph vs affected + shared cache. · Source: GitHub Actions pricing + Latchkey rates
Selective testing needs a trustworthy graph
Selective and impacted testing is only safe when the affected set is complete; a missed edge means a real regression ships green, which is the worst possible outcome for a CI system. This is the asymmetry at the heart of monorepo CI: skipping a target that was truly unaffected saves money with no downside, but skipping a target that a change actually broke ships a bug with a green check. The entire strategy rests on the affected set never being wrong in the dangerous direction.
That is why the teams that run lean monorepo CI confidently invest in keeping the dependency graph accurate. They treat the graph as production infrastructure, not a convenience, because an inaccurate graph quietly converts cost savings into shipped regressions. Implicit dependencies, dynamic imports, and shared configuration that the graph does not capture are the edges that cause unsafe skips, and the disciplined teams hunt them down rather than hoping they do not exist.
They also invest in fast, consistent runners so the occasional full validation run is cheap enough to schedule without flinching. A periodic full-graph build is the safety net that catches anything impact analysis missed, and it is only affordable as a safety net if runners are fast and cheap. The combination, an accurate graph for everyday speed and a cheap full run as a periodic backstop, is what lets teams skip aggressively without ever betting correctness on the graph being perfect.
The tool choice matters less than the commitment
The tool-share chart shows Turborepo, Nx, Bazel, and custom scripts splitting the monorepo market, and teams often agonize over which to pick. But the data underneath the cost charts says the choice between the established tools matters far less than whether a team has committed to affected-target detection at all. The order-of-magnitude savings come from skipping unaffected work and caching results, which every one of these tools supports; the differences between them are real but second-order next to that.
What separates outcomes is commitment to the principle, not selection of the tool. A team running Turborepo without trusting its affected set, or Bazel while still rebuilding the world out of caution, gets the cost of the full-graph build with the complexity of the tool on top. A team that fully commits to building only what changed and caching everything else gets the savings regardless of which of these tools computes the graph for it.
The notable presence of custom scripts in the share chart reinforces the point. A meaningful slice of teams get affected-target detection from hand-rolled scripts rather than a named tool, and they capture most of the benefit because the benefit lives in the principle, not the brand. The practical advice is to pick the tool that fits the stack, then commit fully to skipping and caching, because the commitment is where the order-of-magnitude difference actually comes from.
Cache locality and fast runners are a monorepo-specific edge
In most CI contexts the runner layer is a commodity, but in a monorepo it is a strategic concern, because the whole cost model depends on cheap cache hits and fast turnaround on the affected subset. A monorepo strategy that skips unaffected work and leans on a shared cache is making a bet on infrastructure: that fetching a cached artifact is fast and that running the affected subset is quick. The runner layer is what makes that bet pay or fail.
Cache locality is the clearest example. The shared remote cache that recovers a large fraction of monorepo minutes only does so when the artifact store sits near the runner fleet, so where the runners live relative to the cache is a direct input to the cost. A runner fleet far from its cache turns a winning strategy into a coin flip, which is why cache locality is a runner-layer decision as much as a caching one.
Fast runners compound the advantage. Because the affected subset is the critical path and the periodic full validation is the safety net, both want runners that start quickly and run consistently, so neither the everyday skip nor the occasional full run becomes a bottleneck. Managed runners that keep capacity warm and sit close to the cache attack both the per-minute rate and the locality at once, which is why the runner layer matters more in a monorepo than almost anywhere else in CI.
Recommendations
Adopt affected-target detection before anything else
The full-graph build is the single most expensive mistake in monorepo CI, costing nearly an order of magnitude more than an affected-only build. Adopt Nx, Turborepo, Bazel, or a trustworthy custom equivalent so the pipeline builds and tests only what a change affects and skips the rest. This one inversion makes cost scale with the change instead of the codebase and is the highest-leverage move available.
Treat the dependency graph as production infrastructure
Selective testing is only safe when the affected set is complete, and a missed edge ships a regression green. Invest in keeping the dependency graph accurate, hunting down implicit dependencies, dynamic imports, and shared configuration the graph might miss, because the safety of every skip depends entirely on the graph being right in the dangerous direction.
Share a remote cache and keep it close to the runners
A shared remote cache recovers a large fraction of monorepo minutes, but only when fetching an artifact is faster than recomputing it. Keep the artifact store near the runner fleet so cache hits reliably beat rebuilds; a cache that is shared but distant can be slower than rebuilding small targets and undermines the whole strategy.
Keep a cheap periodic full-graph run as a safety net
Aggressive skipping is only safe with a backstop. Schedule an occasional full-graph validation to catch anything impact analysis missed, and keep runners fast and cheap enough that this safety net is affordable to run regularly. The combination of an accurate graph for everyday speed and a cheap full run as a periodic check lets you skip confidently.
Pick the runner layer for locality and warm capacity
In a monorepo the runner layer is strategic, not a commodity, because the cost model depends on cheap cache hits and fast turnaround on the affected subset. Choose runners that sit close to the shared cache and keep capacity warm so both the everyday skip and the periodic full run stay fast, and use a managed rate to take another bite out of the per-minute cost underneath it all.
Outlook
Expect the gap between affected-only and full-graph monorepo teams to keep widening as repos grow, because the cost penalty of the full-graph build compounds with repository size and merge frequency. The tools to do better are mature and widely adopted, so the teams still building the whole graph in 2026 are doing so by inertia rather than necessity, and they will feel the divergence sharply as their headcount and codebase climb the non-linear curve.
The architectural direction is toward the runner layer becoming a first-class part of monorepo CI strategy rather than an afterthought. Cache locality, warm capacity, and a low per-minute rate all matter more in a monorepo than elsewhere because the whole cost model leans on cheap cache hits and fast turnaround, so the teams that optimize the runner layer alongside their build tool will pull ahead of those that treat runners as a commodity. The build tool and the runner layer are one system.
For most teams the takeaway is that monorepo CI cost is self-inflicted and fixable. The full-graph build is a choice, the tools to skip it are mature, and the levers that close the order-of-magnitude gap, affected detection, an accurate graph, a close shared cache, and fast runners, are mechanical rather than fundamental. The organizations that put them in place keep the developer advantages of the monorepo without the CI liability, while their peers keep paying for their history on every push.
Methodology
This report combines publicly available developer-survey context and published CI pricing with Latchkey's own analysis of monorepo CI economics. Figures labeled "modeled" are illustrative estimates derived from public pricing and typical monorepo graph shapes, not a primary survey. Tool-usage shares are synthesized from public ecosystem data and shown as relative weights. The managed rate and the roughly 69 percent saving are modeled blended figures derived from published per-minute rates (Linux at $0.008/min, managed at $0.0025/min). Savings multiples depend heavily on graph shape and change locality and will vary by repository. 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
- Stack Overflow Developer Survey
- GitHub - Octoverse
- GitHub Actions - billing & pricing
- DORA State of DevOps Report