How to Optimize CI for a Monorepo
The monorepo trap is rebuilding the whole repo for a one-package change. Build only what is affected.
Monorepo CI scales only if it does work proportional to the change, not to the repo. The toolkit is affected detection, scoped checkout, and shared caching.
Build only affected projects
Use Nx affected, Turborepo filters, or Bazel target queries so a change triggers only the packages it touches and their dependents.
Scope the checkout
Sparse-checkout the packages a job needs instead of cloning the whole tree every time.
Share a remote cache
A remote build cache lets unchanged packages return cached results across runners and branches, which is where monorepos win or lose.
Provision per job
Different packages need different resources. Right-sized managed runners (like Latchkey) give a heavy package more RAM and a trivial one a small box, instead of paying one fixed tier for all.
Key takeaways
- Do work proportional to the change, not the repo.
- Affected detection + remote cache are the core levers.
- Right-size runners per package instead of one fixed tier.