Monorepo CI/CD: Caching, Affected Builds,
and Real Build Times in 2026
Most "use caching" advice skips the measured deltas. This page shows real build time numbers, the three CI strategies for monorepos, and the failure modes that kill cache hit rates.
If total CI bill is the driver: CI/CD cost calculator | CI/CD cost guide
The Three CI Strategies
Benchmark Numbers (Cited to Source)
19h (mono) vs 2h (poly) median PR cycle time
Source: Faros AI, 320 engineering teams
PR cycle time measures from first commit to merge. Monorepo PRs are typically larger (touch more packages), which drives the 9x delta. Build time and PR size are confounded. Faros also reports much heavier tails in monorepos (worst-case PRs past ten days), so the median understates the variance.
Why we don't quote a single "X% faster" number
Vendor case studies advertise reductions anywhere from a few percent to 90%+, but they measure different repos, workloads, and baselines, so a single portable figure would be invented precision. The reduction on your repo is bounded by two things you can measure yourself: the share of the task graph a typical PR leaves untouched (the affected-only win) and your cache-hit rate on the tasks that do run (the remote-cache win). A PR touching one leaf package in a 200-package graph skips almost everything; a change to a base library everyone depends on invalidates most of it. Instrument your own pipeline before trusting anyone's headline percentage.
Tool-Specific CI Commands
| Tool | Affected-only command | Remote cache | Distributed builds |
|---|---|---|---|
| Nx | npx nx affected -t build | Nx Cloud (env: NX_CLOUD_ACCESS_TOKEN) | Yes (Nx Agents) |
| Turborepo | npx turbo run build --filter=...[origin/main] | Vercel Remote Cache (env: TURBO_TOKEN) | No |
| Bazel | bazel build //... --build_event_stream=... | BuildBuddy / EngFlow remote cache | Yes (BuildFarm) |
| Rush | rush build --to-except-point <sha> | Azure Blob / S3 (custom setup) | Partial |
| Pants | pants --changed-since=main build :: | Toolchain remote cache | Yes (remote execution) |
Common CI Failure Modes in Monorepos
Cache poisoning
HighNon-deterministic build writes wrong artifact to cache. Subsequent runs use poisoned artifact. Fix: ensure build outputs are determined only by inputs (no timestamps, random seeds, env vars not hashed).
Untracked dependencies
HighA build task depends on a file not declared in its input set. Changes to that file don't invalidate the cache. Fix: declare all file inputs explicitly in nx.json inputs or turbo.json inputs.
Cache hit rate collapse
MediumLarge packages or packages with many dependents make almost every PR's cache stale. Fix: split large packages into smaller ones; be explicit about outputs.
Partial-clone issues
Mediumgit clone --depth=1 in CI causes nx affected to fail (no full history to compare against main). Fix: use fetch-depth: 0 or fetch the base branch explicitly.
Flaky tests polluting cache
MediumA flaky test passes and caches its result. Next run returns cached 'pass'. Flakiness hidden by cache. Fix: mark known-flaky tests as no-cache; track flakiness in CI observability.