2 min read

Monorepo Build Graph Optimization

Strategies to reduce monorepo build time through change impact calculation and cache key design

Monorepo Build Graph Optimization thumbnail

Introduction

Monorepo is highly collaborative, but CI quickly becomes a bottleneck if you don't manage the build graph. If full rebuilds become the default, waiting times for even small changes will increase, breaking the development rhythm. This article summarizes the dependency graph-based incremental build strategy.

Monorepo Build Graph 최적화 커버
Wikimedia Commons 기반 무료 이미지

Problem definition

The cost of building a monorepo depends on graph design rather than repository size.

  • The scope of change impact cannot be calculated because the package boundary is ambiguous.
  • Because the cache key is simple, cache misses occur frequently even with the same input.
  • Because the test scope is excessive, jobs unrelated to core changes are executed.

The key is to declare the graph in code and have the pipeline trust it. The affected-only strategy should be the default.

Key concepts

perspectiveDesign criteriaVerification points
graph declarationSpecifying package dependenciesImpact calculation accuracy
Incremental Buildrun affected targetAverage Build Time
remote cachehash-based reusecache hit ratio
Test OptimizationTest by change boundaryUnnecessary miscellaneous rate

Monorepo optimization involves defining rules before introducing tools. Strictly managing package boundaries simplifies the build graph and stabilizes performance.

Code example 1: Example build graph declaration

{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"]
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": ["coverage/**"]
    },
    "lint": {
      "outputs": []
    }
  }
}

Code example 2: Calculating affected packages

#!/usr/bin/env bash
set -euo pipefail

BASE=\${1:-origin/main}

pnpm turbo run build test \
  --filter="...[\${BASE}]" \
  --cache-dir=.turbo/cache \
  --summarize

Architecture flow

Mermaid diagram rendering...

Tradeoffs

  • Graph-based optimization is difficult to set up initially, but significantly reduces long-term CI costs.
  • Remote cache is advantageous for speed, but requires cache consistency management.
  • The affected-only strategy is efficient, but there is a risk of regression when graphs are missing.

Cleanup

Monorepo performance is determined by graph accuracy rather than build tools. Clear dependency boundaries and default to incremental execution can help you maintain a fast development loop even on large repositories.

Image source

  • Cover: source link
  • License: CC BY 2.0 / Author: Paul Hudson from United Kingdom
  • Note: After downloading the free license image from Wikimedia Commons, it was optimized to JPG at 1600px.

Comments