Skip to content

SYSTEM Cited by 1 source

Turborepo

Turborepo is Vercel's Rust-written task runner for JavaScript + TypeScript monorepos. turbo run <task> analyses the monorepo's package.json structure, scripts, and dependencies to build a task graph (the DAG of what depends on what), then executes tasks in parallel where the DAG permits and caches per-task outputs so repeated work is skipped.

Architecture at a glance

The Rust-authored CLI (turbo) is the whole product — there is no orchestrator / worker split. Every invocation does:

  1. Repo inference — find the monorepo root.
  2. Package + lockfile discovery — parse every package.json + the lockfile to build the package graph.
  3. Task-graph construction — for the requested task, walk the task dependency declarations (dependsOn in turbo.json) to produce the full DAG of task executions needed.
  4. Cache-key hashing — each task node is keyed by a content-addressed digest of its inputs (source files, task definition, environment, Turborepo version).
  5. Execution — run tasks in parallel topological order; for each task, check cache, run on miss, write cache on success.

Task-graph construction as a first-order cost

Building the task graph is overhead paid before the first task runs. On a 1,000-package monorepo this was 8.1 s in Turborepo v2.8.0 — a substantial tax on every turbo run invocation, paid even when the cache is hot and no real work needs to run. The 2026-04-21 Making Turborepo 96 % faster post is the retrospective of an 8-day campaign that drove this down to 716 ms (91 % faster; 11× speedup) in v2.9.0.

Canonical v2.8.0 → v2.9.0 regression table:

Repo size v2.8.0 v2.9.0 Improvement
~1,000 packages 8.1 s 0.716 s 91 %
132 packages 1.9 s 361 ms 81 %
6 packages 676 ms 132 ms 80 %

Profile infrastructure

Turborepo ships a --profile <file> flag that writes a Chrome Trace Event Format JSON file (consumable by Perfetto or chrome://tracing). As of PR #11880 (2026-04, the turborepo-profile-md crate), Turborepo also emits a companion Markdown profile alongside the JSON with the same per-span data reorganised for agent consumption — see patterns/markdown-profile-output-for-agents and concepts/markdown-as-agent-friendly-format.

The Markdown format:

  • Hot functions sorted by self-time (top-N table)
  • Full call tree sorted by total-time
  • Caller/callee relationships
  • All single-line, grep-friendly, column-aligned

The post's canonical verbatim datum on the format choice: "Same model, same codebase, same data, same agent harness. Different format, radically better optimization suggestions."

Performance-engineering wins (v2.9.0)

The v2.8.0 → v2.9.0 campaign fell into three named categories:

Parallelisation — git index, filesystem glob walk, lockfile parsing, package.json loading all moved from sequential to concurrent.

Allocation elimination — hashing by reference instead of cloning HashMaps; pre-compiled glob exclusion filters; shared HTTP client instead of per-request construction; stack-allocated OidHash ([u8; 40]) replacing heap- allocated SHA-1 String (the PR #11984 removed 10,000+ 40-byte heap allocations per run on the 1000-package repo, with new_from_gix_index self-time dropping 15 % and get_package_file_hashes_from_index dropping 17 %; also canonicalised the run-to-run variance wins at 48 % / 57 % / 61 % reduction across three repo sizes).

Syscall reduction — per-package git subprocess calls → single repo-wide index (#11887); git subprocesses → libgit2 (#11938); libgit2gix-index (#11950). Cache-fetch syscall elimination (#11985) removed a legacy Golang-era .tar cache-format probe (returned ENOENT every time) — 35 % reduction on fetch self-time over 962 cache fetches.

Dogfooding

Turborepo is built with Turborepo — the Rust codebase's own build runs through turbo. This dogfood loop enables end-to-end validation (building the current turbo binary and running it on the Turborepo source tree as the benchmark workload), which Shew flags as something unattended agents missed: "The agent never realized it could benchmark the improvements on the Turborepo codebase itself." See concepts/agent-hyperfixation-failure-mode.

Cache format lineage

Turborepo's Go → Rust rewrite (2021-2022) left a compatibility tail: the current cache reader continued to probe for uncompressed .tar cache entries even though no modern Turborepo version writes them. The PR #11985 syscall-elimination commit removed this probe — a canonical example of dead compatibility costing real syscalls on the hot path, identifiable only by reading the profile (cache entries rotate out constantly so the .tar path never hits).

Seen in

  • Making Turborepo 96 % faster with agents, sandboxes, and humans (Vercel, 2026-04-21) — the definitional Turborepo-performance-engineering retrospective; 8-day agent-assisted campaign; 91 % Time to First Task improvement on 1000-package repo; Markdown profile tooling + Sandbox benchmarking + supervised Plan-Mode agent loop as three load-bearing techniques.
Last updated · 476 distilled / 1,218 read