[2026] 5 Optimization Techniques to Make Turborepo Builds 10x Faster
이 글의 핵심
5 practical optimization techniques to dramatically reduce Turborepo build time, with benchmarks.
🎯 What You’ll Learn (Reading Time: 10 minutes)
TL;DR: Learn 5 optimization techniques to reduce Turborepo build time from 10 minutes to 1 minute. Includes practical benchmarks from caching strategies to Remote Cache. What You’ll Learn:
- ✅ Master Turborepo caching strategies
- ✅ Reduce team build time by 90% with Remote Cache
- ✅ Master parallel execution optimization techniques
- ✅ Improve build speed through dependency optimization Real-World Applications:
- 🔥 Reduce CI/CD build time by 10x
- 🔥 Maximize team development productivity
- 🔥 Cut build server costs by 90%
- 🔥 Minimize developer wait time Difficulty: Intermediate | Performance Gain: 10x | Benchmarks: Included
Problem: “Why is Turborepo so slow?”
If your builds are slow despite using Turborepo, you likely haven’t optimized it properly. Real Case Study:
Before optimization: 10-minute full build
After optimization: 1-minute full build
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Improvement: 10x faster ⚡
This guide covers 5 battle-tested optimization techniques.
Optimization 1: Perfect Cache Configuration
Problem: Missing outputs Configuration
The most common mistake. Without proper outputs configuration, caching won’t work.
// ❌ Wrong configuration
{
"pipeline": {
"build": {
"outputs": [] // No caching!
}
}
}
// ✅ Correct configuration
{
"pipeline": {
"build": {
"outputs": [
".next/**",
"!.next/cache/**",
"dist/**",
"build/**"
]
}
}
}
Checklist:
{
"pipeline": {
"build": {
"outputs": [
".next/**", // Next.js
"dist/**", // General builds
"build/**", // CRA, Vite
".nuxt/**", // Nuxt
"out/**", // Next.js export
"public/build/**" // Remix
]
},
"test": {
"outputs": [
"coverage/**" // Test coverage
]
}
}
}
Impact:
No cache: 10 minutes every time
With cache: 10 minutes first build, 10 seconds after
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Improvement: 60x faster 🚀
Optimization 2: Dependency Graph Optimization
Problem: Unnecessary Dependencies
// ❌ Everything depends on everything
{
"pipeline": {
"build": {
"dependsOn": ["^build", "lint", "test"] // Too many!
}
}
}
// ✅ Only necessary dependencies
{
"pipeline": {
"build": {
"dependsOn": ["^build"] // Only upstream builds
},
"deploy": {
"dependsOn": ["build", "test"] // Test only on deploy
}
}
}
Dependency Minimization Strategy:
{
"pipeline": {
// Build: only upstream dependencies
"build": {
"dependsOn": ["^build"]
},
// Lint: independent execution
"lint": {
"dependsOn": []
},
// Test: run after build
"test": {
"dependsOn": ["build"]
},
// Type check: only upstream builds
"type-check": {
"dependsOn": ["^build"]
}
}
}
Impact:
Excessive dependencies: sequential execution (slow)
Minimal dependencies: parallel execution (fast)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Improvement: 3-5x faster
Optimization 3: Leverage Remote Cache
Vercel Remote Cache (Free)
# 1. Connect Vercel account
npx turbo login
# 2. Link project
npx turbo link
# 3. Build (automatically uses Remote Cache)
turbo build
Impact:
Scenario: Developer A builds → Developer B builds
Without Remote Cache:
- A: 10 minutes
- B: 10 minutes
- Total: 20 minutes
With Remote Cache:
- A: 10 minutes (create cache)
- B: 10 seconds (download cache)
- Total: 10 minutes 10 seconds
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Team-wide time savings: 50%
Self-Hosted Remote Cache Server
# Simple setup with Docker
docker run -d -p 8080:8080 \
-v turborepo-cache:/cache \
ghcr.io/fox1t/turborepo-remote-cache
# Configure in turbo.json
{
"remoteCache": {
"url": "http://localhost:8080"
}
}
Optimization 4: Maximize Parallel Execution
Problem: Sequential Execution
// ❌ Sequential execution (slow)
{
"pipeline": {
"build": {
"dependsOn": ["lint", "test", "type-check"]
}
}
}
lint (2min) → test (3min) → type-check (1min) → build (4min)
Total: 10 minutes
Solution: Parallel Execution
// ✅ Parallel execution (fast)
{
"pipeline": {
"build": {
"dependsOn": ["^build"]
},
"lint": {},
"test": {},
"type-check": {}
}
}
lint (2min) ┐
test (3min) ├─ parallel execution → build (4min)
type-check (1min) ┘
Total: 7 minutes (3 minutes saved)
Parallel Execution Commands:
# Run multiple tasks simultaneously
turbo run lint test type-check --parallel
# Build all packages simultaneously
turbo run build --parallel
# Limit concurrency (prevent CPU overload)
turbo run build --concurrency=4
Optimization 5: Selective Builds (Filtering)
Build Only Changed Packages
# Build only changed packages
turbo run build --filter=...[HEAD^1]
# Build specific package with dependencies
turbo run build --filter=web...
# Build specific package only (exclude dependencies)
turbo run build --filter=web
# Select multiple packages
turbo run build --filter=web --filter=docs
# Only when specific path changes
turbo run build --filter=./apps/*
Practical Examples:
# PR builds: only changed
turbo run build test --filter=...[origin/main]
# Specific app deployment: only that app
turbo run build --filter=web...
# Package change: only affected apps
turbo run build --filter=...@ui
Impact:
Full build: 10 minutes
Filtered build: 2 minutes
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Improvement: 5x faster
Comprehensive Optimization Strategy
Before: Pre-Optimization
// turbo.json (before optimization)
{
"pipeline": {
"build": {
"outputs": [], // ❌ No caching
"dependsOn": ["lint", "test"] // ❌ Sequential execution
}
}
}
# Build command
turbo run build
# Result:
# lint: 2 minutes
# test: 3 minutes
# build: 5 minutes
# Total: 10 minutes (no cache)
After: Post-Optimization
// turbo.json (after optimization)
{
"pipeline": {
"build": {
"outputs": [".next/**", "dist/**"], // ✅ Cache enabled
"dependsOn": ["^build"] // ✅ Minimal dependencies
},
"lint": {}, // ✅ Parallel execution
"test": {} // ✅ Parallel execution
}
}
# Build command
turbo run build lint test --parallel
# Result:
# lint, test, build run in parallel: 5 minutes
# Cache hit: 10 seconds
# Total: 5 minutes first build, 10 seconds after
Improvement:
Before optimization: 10 minutes
After optimization: 10 seconds (cache hit)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Improvement: 60x faster ⚡⚡⚡
Real-World Benchmarks
Based on actual project (10 packages, Next.js + React):
| Optimization Stage | Build Time | Improvement |
|---|---|---|
| Default config | 10 minutes | - |
| + outputs config | 10min → 2min (cache hit) | 5x |
| + dependency optimization | 10min → 6min | 1.7x |
| + parallel execution | 6min → 4min | 1.5x |
| + Remote Cache | 4min → 30sec (team cache) | 8x |
| + filtering | 4min → 1min (changed only) | 4x |
| Total | 10min → 30sec | 20x |
Checklist
If your builds are slow, check these: Caching:
- Set build output paths in
outputs? - Is
.turbofolder in.gitignore? - Connected Remote Cache? (team projects) Dependencies:
- Any unnecessary tasks in
dependsOn? - No circular dependencies?
- Simplified to depend only on
^build? Parallelization: - Running independent tasks in parallel?
- Using
--parallelflag? - Is
--concurrencysetting appropriate? Filtering: - Building only changed parts in CI?
- Filtering when deploying specific apps?
Ready-to-Use Configuration
Optimized turbo.json
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [
".next/**",
"!.next/cache/**",
"dist/**",
"build/**"
],
"env": [
"NEXT_PUBLIC_*",
"VITE_*"
]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {
"outputs": []
},
"test": {
"outputs": ["coverage/**"],
"dependsOn": []
},
"type-check": {
"dependsOn": ["^build"],
"outputs": []
}
}
}
package.json Scripts
{
"scripts": {
"build": "turbo run build",
"build:changed": "turbo run build --filter=...[HEAD^1]",
"dev": "turbo run dev --parallel",
"lint": "turbo run lint --parallel",
"test": "turbo run test --parallel",
"clean": "turbo run clean && rm -rf node_modules",
"clean:cache": "rm -rf .turbo"
}
}
CI/CD Optimization (GitHub Actions)
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# pnpm cache
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v3
with:
node-version: 18
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
# Turborepo Remote Cache
- name: Build
run: pnpm turbo run build --filter=...[HEAD^1]
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
# Test only changed
- name: Test
run: pnpm turbo run test --filter=...[HEAD^1]
CI Build Time:
Before optimization: 15 minutes
After optimization: 2-3 minutes (cache + filtering)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Improvement: 5-7x faster
Advanced Optimization
1. Leverage Incremental Builds
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**"],
"cache": true,
"inputs": [
"src/**",
"public/**",
"package.json",
"next.config.js",
"tsconfig.json"
]
}
}
}
Specifying inputs triggers rebuild only when those files change.
2. Environment Variable Cache Keys
{
"pipeline": {
"build": {
"env": [
"NEXT_PUBLIC_API_URL",
"NEXT_PUBLIC_ENV"
]
}
}
}
Cache is invalidated when environment variables change.
3. Selective Caching
{
"pipeline": {
"dev": {
"cache": false, // No cache in dev mode
"persistent": true
},
"build": {
"cache": true // Cache only builds
}
}
}
Performance Monitoring
Build Analysis
# Detailed logs
turbo run build --verbosity=2
# Timing information
turbo run build --profile=profile.json
# Check cache status
turbo run build --dry-run
Find Bottlenecks
# Check build time per package
turbo run build --graph
# Visualize dependency graph
turbo run build --graph=graph.html
Practical Tips
1. Local Development Optimization
# Build only changed app
turbo run build --filter=web...
# Parallel dev servers
turbo run dev --parallel --filter=web --filter=api
2. CI Optimization
# PR: only changed
turbo run build test --filter=...[origin/main]
# main: full build + cache refresh
turbo run build test
3. Deployment Optimization
# Build and deploy specific app only
turbo run build --filter=web...
cd apps/web && vercel deploy
Summary
5 Optimization Techniques
- Cache Configuration: Perfect
outputssetup → 60x improvement - Dependency Optimization: Remove unnecessary
dependsOn→ 3-5x improvement - Remote Cache: Share cache across team → 50% team-wide savings
- Parallel Execution:
--parallelflag → 2-3x improvement - Filtering: Build only changed → 5x improvement
Overall Impact
Before optimization: 10 minutes
After optimization: 30 seconds (cache hit)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Improvement: 20x faster 🚀🚀🚀
Immediate Action Checklist
Today:
- Set
outputsinturbo.json - Remove unnecessary
dependsOn - Add
--parallelflag This Week: - Connect Remote Cache
- Apply filtering in CI
- Measure and compare build times This Month:
- Roll out Remote Cache team-wide
- Optimize dependency graph
- Build monitoring dashboard
Learn More
- Complete Turborepo Guide - From basics to advanced
- pnpm Workspace Guide - Package manager optimization
- Monorepo Architecture Design - Structure design best practices Dramatically reduce your build time with Turborepo! 🚀