Skip to content

perf: Index Berry lockfile resolution overrides by dependency name - #13787

Merged
anthonyshew merged 1 commit into
mainfrom
agents/performance-6486-06-05
Aug 20, 2026
Merged

anthonyshew merged 1 commit into
mainfrom
agents/performance-6486-06-05

Conversation

@vercel-gh-bot-5

Copy link
Copy Markdown
Contributor

Summary

Berry (Yarn v2+) lockfile analysis previously performed a linear scan over every root resolutions override for every dependency edge, both while parsing the lockfile (populate_extensions visits every package × dependency) and again while computing per-workspace transitive closures (resolve_package / all_dependencies). On repos with many overrides this is O(edges × overrides): cal.com has 91 resolutions entries and a 113-package workspace, so the override scan dominated Berry resolution time.

This change groups the overrides once at lockfile construction into an FxHashMap<String, Vec<(Resolution, String)>> keyed by the unscoped name of the package each override targets, so each edge does a single hash lookup instead of scanning all overrides.

Correctness invariants preserved:

  • Resolution::reduce_dependency returns None whenever the resolution's descriptor ident differs from the dependency's ident, so overrides targeting other names can never match — bucketing removes only never-matching candidates.

  • Scoped/unscoped packages sharing a name land in the same bucket and are still disambiguated by the existing full-ident check inside reduce_dependency.

  • Buckets are filled by iterating the previous ordered BTreeMap<Resolution, String>, preserving relative order, so first-match-wins semantics are unchanged.

  • The map is Arc-shared so subgraph() (used by turbo prune) clones become refcount bumps; an is_empty guard keeps repos without resolutions on a trivial path.

  • Author model: anthropic/claude-fable-5

  • Reviewer model: openai/gpt-5.6-sol (gpt_performance_reviewer)

Hypothesis (declared before editing)

Replacing the per-edge linear override scan with a per-name index reduces the median wall time of turbo run build --dry=json --no-daemon on the pinned cal.com checkout by a nonzero amount with identical outputs, at the cost of one small extra hash map per lockfile.

Methodology

  • Environment: Ubuntu 26.04 container, kernel 6.18.40, x86_64, Intel Xeon @ 2.90 GHz, 2 vCPU, 4283 MB RAM, low background load; rustc 1.97.0-nightly (e96c36b6f, repo toolchain nightly-2026-05-22); hyperfine 1.19.0; valgrind/callgrind 3.26.0.
  • Corpus (cloned outside the checkout, detached at pinned revisions): calcom/cal.com @ 176037d0afbe572f870a3c702985e7cd83fe6c0c (yarn berry, 113 packages, 91 resolutions, 115 build tasks in the dry run) as the primary affected workload; t3-oss/create-t3-turbo @ 8f945b7bb3bfb3ca8358d48b1ff0214079bc11ee (pnpm) as an untouched-path check. (trigger.dev's pinned revision still uses turbo-1.x pipeline config and fails identically under both binaries, so it cannot serve as a timing workload.)
  • Both binaries built with the identical command cargo build --profile release-turborepo -p turbo and preserved outside the checkout: baseline fba922b4… (50,459,232 B, from the clean checkout, verified bit-identical to a clean rebuild), candidate f282ff58… (50,462,240 B, +3,008 B).
  • Timing harness: hyperfine, --warmup 3 --runs 10 per binary per block, both binaries inside one invocation, balanced AB/BA block ordering, warm caches with identical preparation, non-mutating dry-run command, daemon unused. Inference is block-aware: per-block median speedups, sign test, and a seeded 20k-resample percentile bootstrap over block speedups.

Evidence

End-to-end (cal.com, turbo run build --dry=json --no-daemon):

  • Clean-checkout baseline phase: mean 148.2 ms ± 15.3 (20 runs). Post-edit after phase (identical command text): mean 125.8 ms ± 5.7 (20 runs).
  • Final recorded comparison set (6 balanced AB/BA blocks, 60 samples per binary): block-median speedups [+6.61, +3.69, +4.13, −1.34, +6.93, +5.46]%; 5/6 positive; both orders improve on average; mean +4.25%, bootstrap 95% CI [+1.81%, +6.11%]. The one negative block contains visible transient load spikes in its candidate runs (129→168 ms outliers) and was retained per the predeclared no-removal rule.
  • Cumulative across all 22 balanced blocks run this session (identical protocol/binaries/corpus): 21/22 positive; sign test p = 5.5e-6; AB mean +6.02%, BA mean +3.82%; bootstrap mean +4.92%, 95% CI [+3.88%, +5.97%]; pooled medians 133 ms → 125–126 ms (−5 to −8 ms per invocation).

Targeted mechanism benchmark (standalone harness outside the checkout; 5× BerryLockfile::new + transitive_closure per invocation on a pinned cal.com fixture; identical checksums 22825 from both builds; separate optimized builds with the diff stashed vs applied): 4/4 balanced AB/BA blocks positive, mean +17.23%, 95% CI [+16.09%, +18.05%] (40 samples per binary). Each invocation also carries ~35–40 ms of fixed untouched YAML-parse work, so the improvement on the changed code itself is larger.

Callgrind (deterministic instruction counts, one dry run per binary): total Ir 1,149,102,165 → 1,000,185,424 (−13.0%); Resolution::reduce_dependency 75.08 M → 0.18 M Ir (−99.8%); BerryLockfile::resolve_dependency 52.94 M → 1.69 M Ir (−96.8%).

Untouched pnpm path (create-t3-turbo): 4 balanced blocks, no statistically detectable difference (bootstrap 95% CI [−2.54%, +0.51%], spans zero) — consistent with the diff touching only berry/ code.

Correctness

  • cargo test -p turborepo-lockfiles: 314/314 pass (includes berry override/patch/prune/subgraph/resolution tests).
  • cargo clippy -p turborepo-lockfiles --all-targets -- -D warnings and cargo fmt --check: clean.
  • cal.com and create-t3-turbo --dry=json outputs are byte-identical between baseline and candidate except the random run id (all 115 task hashes and globalCacheInputs identical).
  • turbo prune @calcom/web (exercises subgraph() and pruned yarn.lock serialization): output directories byte-identical (diff -r clean).

Adversarial review

gpt_performance_reviewer (opposite model) reviewed the complete diff and evidence across four rounds. Earlier rounds requested stronger statistics (raw per-run data, more balanced blocks, block-aware CI), withdrawal of an unsupported scaling claim, and a targeted benchmark of the mechanism; all findings were resolved. Final verdict: approved, no blocking findings — "the replacement official timing set satisfies the stated acceptance criteria … a 95% CI wholly above zero ([+1.81%, +6.11%]) … the targeted benchmark and Callgrind diagnostics are directionally consistent with eliminating the per-edge override scan. The final claim is appropriately limited to cal.com rather than generalized to unaffected repositories."

Limitations / tradeoffs

  • The measured wall-time claim is limited to the pinned cal.com workload (~4–5%, −5 to −8 ms per ~130 ms dry run on 2 vCPUs); CPU-time and instruction reductions are larger (−13% instructions). Repos without berry resolutions are unaffected; no timing claim is made for other repositories.
  • +3,008 bytes binary size (+0.006%); one extra FxHashMap holding ~one entry per resolutions override per BerryLockfile, Arc-shared across subgraphs.

@vercel

vercel Bot commented Aug 20, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
examples-basic-web Ready Ready Preview Aug 20, 2026 5:32pm
examples-designsystem-docs Ready Ready Preview Aug 20, 2026 5:32pm
examples-gatsby-web Ready Ready Preview Aug 20, 2026 5:32pm
examples-kitchensink-blog Ready Ready Preview Aug 20, 2026 5:32pm
examples-nonmonorepo Ready Ready Preview Aug 20, 2026 5:32pm
examples-svelte-web Ready Ready Preview Aug 20, 2026 5:32pm
examples-tailwind-web Ready Ready Preview Aug 20, 2026 5:32pm
examples-vite-web Ready Ready Preview Aug 20, 2026 5:32pm
turbo-site Ready Ready Preview Aug 20, 2026 5:32pm
turborepo-factory Ready Ready Preview Aug 20, 2026 5:32pm

@anthonyshew
anthonyshew marked this pull request as ready for review August 20, 2026 17:43
@anthonyshew
anthonyshew requested review from a team and tknickman August 20, 2026 17:43
@anthonyshew
anthonyshew merged commit e89eddd into main Aug 20, 2026
54 of 55 checks passed
@anthonyshew
anthonyshew deleted the agents/performance-6486-06-05 branch August 20, 2026 17:44
github-actions Bot added a commit that referenced this pull request Aug 25, 2026
## Release v2.10.12

> [!CAUTION]
> Versioned docs aliasing FAILED. [View
logs](https://github.com/vercel/turborepo/actions/runs/32882264217)

### Changes

- chore: Release Turborepo 2.10.11 (#13765) (`1fb1e86`)
- feat: Refresh documentation social cards (#13764) (`510777b`)
- fix: Preserve showcase logo sizes (#13766) (`b03ec9d`)
- fix: Refine mobile homepage interactions (#13767) (`a253dce`)
- fix: Align homepage KPIs to the right (#13769) (`373fbd3`)
- fix: Prevent homepage KPI overflow (#13770) (`fc02d72`)
- chore: Update Geistdocs to 1.20.4 (#13771) (`0689ad9`)
- perf: Skip Unused Workspace Config Stats (#13746) (`5503fde`)
- chore: Update with-solid example (#13752) (`43c555d`)
- chore: Update with-tailwind example (#13762) (`c436362`)
- perf: Stream dry-run JSON output (#13760) (`8138ce0`)
- chore: Update with-ultracite example (#13772) (`37be819`)
- perf: Merge same-prefix tree-wildcard globs into one directory walk
(#13763) (`59d4901`)
- chore: Update with-svelte example (#13118) (`bebcfc8`)
- chore: Add unified agent control plane (#13757) (`695a172`)
- fix: Remove incremental task caching (#13773) (`3d69e42`)
- chore: Rename agents app to factory (#13774) (`0a01c2d`)
- chore: Update oxlint and oxfmt (#13777) (`9088245`)
- feat: Add security.txt endpoint (#13778) (`5f9260b`)
- feat: Redesign factory control plane (#13775) (`ffd06d4`)
- perf: Replace regex captures with hand-written parsers in berry
lockfile identifiers (#13776) (`00e9f66`)
- chore: Upgrade the factory eve agent to 0.39.3 (#13783) (`c4fc5c8`)
- chore: Update with-rsbuild-module-federation example (#13786)
(`45b1257`)
- perf: Index Berry lockfile resolution overrides by dependency name
(#13787) (`e89eddd`)
- chore: Update remote cache action to v1.1.0 (#13789) (`56162b8`)
- docs: Fix reference links and validation (#13784) (`0423d70`)
- feat: Add SSH command affordance for factory sandboxes (#13779)
(`0cfccdd`)
- fix: Show invalid affected task glob (#13793) (`ef1ef92`)
- perf: Skip unused repository indexing for package listings (#13792)
(`acd5ae5`)
- feat: Rebuild the factory image on every merge to main (#13781)
(`1c165b3`)
- chore: Add full-page terminal SSH sessions to Factory sandbox
inventory (#13780) (`d640c2e`)
- chore: Update with-shell-commands example (#13791) (`476e382`)
- chore: Allow SSH terminal for completed-run sandboxes in Factory
(#13782) (`067dfba`)
- fix: Decouple graceful shutdown tests from the shell commands example
(#13799) (`72fac33`)
- feat: Start ad-hoc factory work from the operator page (#13798)
(`b9d13ca`)
- chore: Update with-solid example (#13797) (`d412981`)
- fix: Rebuild factory images without custom workflows (#13801)
(`0c54a80`)
- feat: Add factory navigation (#13802) (`092ee6d`)
- refactor: Migrate Factory styles to Tailwind (#13803) (`7fe373b`)
- feat: Add durable Factory workspaces (#13804) (`ccd79d3`)
- feat: Stream Factory sandbox as terminal (#13807) (`33d8b24`)
- fix: Restore Factory workspace creation (#13812) (`fd72cca`)
- fix: Update Factory session network policy (#13814) (`c579fec`)
- fix: Improve Factory terminal line spacing (#13815) (`a88e39b`)
- fix: Install Factory publishing skill (#13817) (`7b8cb14`)
- chore: Route Factory publishing through Eve (#13816) (`e05b81c`)
- feat: Standardize Factory meta titles to Turborepo suffix (#13819)
(`fd593b5`)
- perf: Skip Factory chat verification (#13820) (`39137a6`)
- fix: Restore Factory workspaces (#13823) (`0afd4b2`)
- docs: Fix inconsistent Yarn command in basic example (#13825)
(`3dd49d1`)
- chore: Update non-monorepo example (#13808) (`d2a673f`)
- perf: Batch package detail queries (#13809) (`331183e`)
- chore: Update basic example (#13824) (`f06836d`)
- fix: Include virtual tasks in affected query (#13805) (`89a9b78`)
- fix: Add workspace approval controls (#13827) (`02dfd21`)
- fix: Prevent chat SSH command overflow (#13828) (`d9eaff5`)
- fix: Update Factory pull request branches (#13831) (`b670754`)
- chore: Add operator chat model selector (#13833) (`bb2fcb3`)
- fix: Move model selector to workspace creation (#13835) (`72805d7`)
- chore: Skip redundant Factory PR approval (#13837) (`bbe5406`)
- chore: Use geistdocs 1.23.1 (#13834) (`3787c06`)
- chore: Handle feedback on Factory pull requests (#13836) (`a76330b`)
- fix: Escape ampersands in RSS feed enclosure URLs (#13839) (`7107f26`)
- chore: Add automatic issue handling (#13840) (`e1674e4`)
- chore: Alert Slack for low-confidence issues (#13841) (`f153cda`)
- feat: Require high confidence for issue fixes (#13842) (`c97782b`)
- fix: Run pnpm directly on Windows (#13843) (`9d2b03b`)

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
anthonyshew pushed a commit that referenced this pull request Aug 27, 2026
## Release v2.10.13-canary.1

> [!CAUTION]
> Versioned docs aliasing FAILED. [View
logs](https://github.com/vercel/turborepo/actions/runs/33018929115)

### Changes

- chore: Release Turborepo 2.10.11-canary.4 (#13759) (`9f94a7d`)
- feat: Expand performance agent toolbox (#13761) (`f924510`)
- docs: Redesign Turborepo homepage (#13702) (`09bf969`)
- fix: Tolerate transient input files (#13734) (`3226457`)
- chore: Release Turborepo 2.10.11 (#13765) (`1fb1e86`)
- feat: Refresh documentation social cards (#13764) (`510777b`)
- fix: Preserve showcase logo sizes (#13766) (`b03ec9d`)
- fix: Refine mobile homepage interactions (#13767) (`a253dce`)
- fix: Align homepage KPIs to the right (#13769) (`373fbd3`)
- fix: Prevent homepage KPI overflow (#13770) (`fc02d72`)
- chore: Update Geistdocs to 1.20.4 (#13771) (`0689ad9`)
- perf: Skip Unused Workspace Config Stats (#13746) (`5503fde`)
- chore: Update with-solid example (#13752) (`43c555d`)
- chore: Update with-tailwind example (#13762) (`c436362`)
- perf: Stream dry-run JSON output (#13760) (`8138ce0`)
- chore: Update with-ultracite example (#13772) (`37be819`)
- perf: Merge same-prefix tree-wildcard globs into one directory walk
(#13763) (`59d4901`)
- chore: Update with-svelte example (#13118) (`bebcfc8`)
- chore: Add unified agent control plane (#13757) (`695a172`)
- fix: Remove incremental task caching (#13773) (`3d69e42`)
- chore: Rename agents app to factory (#13774) (`0a01c2d`)
- chore: Update oxlint and oxfmt (#13777) (`9088245`)
- feat: Add security.txt endpoint (#13778) (`5f9260b`)
- feat: Redesign factory control plane (#13775) (`ffd06d4`)
- perf: Replace regex captures with hand-written parsers in berry
lockfile identifiers (#13776) (`00e9f66`)
- chore: Upgrade the factory eve agent to 0.39.3 (#13783) (`c4fc5c8`)
- chore: Update with-rsbuild-module-federation example (#13786)
(`45b1257`)
- perf: Index Berry lockfile resolution overrides by dependency name
(#13787) (`e89eddd`)
- chore: Update remote cache action to v1.1.0 (#13789) (`56162b8`)
- docs: Fix reference links and validation (#13784) (`0423d70`)
- feat: Add SSH command affordance for factory sandboxes (#13779)
(`0cfccdd`)
- fix: Show invalid affected task glob (#13793) (`ef1ef92`)
- perf: Skip unused repository indexing for package listings (#13792)
(`acd5ae5`)
- feat: Rebuild the factory image on every merge to main (#13781)
(`1c165b3`)
- chore: Add full-page terminal SSH sessions to Factory sandbox
inventory (#13780) (`d640c2e`)
- chore: Update with-shell-commands example (#13791) (`476e382`)
- chore: Allow SSH terminal for completed-run sandboxes in Factory
(#13782) (`067dfba`)
- fix: Decouple graceful shutdown tests from the shell commands example
(#13799) (`72fac33`)
- feat: Start ad-hoc factory work from the operator page (#13798)
(`b9d13ca`)
- chore: Update with-solid example (#13797) (`d412981`)
- fix: Rebuild factory images without custom workflows (#13801)
(`0c54a80`)
- feat: Add factory navigation (#13802) (`092ee6d`)
- refactor: Migrate Factory styles to Tailwind (#13803) (`7fe373b`)
- feat: Add durable Factory workspaces (#13804) (`ccd79d3`)
- feat: Stream Factory sandbox as terminal (#13807) (`33d8b24`)
- fix: Restore Factory workspace creation (#13812) (`fd72cca`)
- fix: Update Factory session network policy (#13814) (`c579fec`)
- fix: Improve Factory terminal line spacing (#13815) (`a88e39b`)
- fix: Install Factory publishing skill (#13817) (`7b8cb14`)
- chore: Route Factory publishing through Eve (#13816) (`e05b81c`)
- feat: Standardize Factory meta titles to Turborepo suffix (#13819)
(`fd593b5`)
- perf: Skip Factory chat verification (#13820) (`39137a6`)
- fix: Restore Factory workspaces (#13823) (`0afd4b2`)
- docs: Fix inconsistent Yarn command in basic example (#13825)
(`3dd49d1`)
- chore: Update non-monorepo example (#13808) (`d2a673f`)
- perf: Batch package detail queries (#13809) (`331183e`)
- chore: Update basic example (#13824) (`f06836d`)
- fix: Include virtual tasks in affected query (#13805) (`89a9b78`)
- fix: Add workspace approval controls (#13827) (`02dfd21`)
- fix: Prevent chat SSH command overflow (#13828) (`d9eaff5`)
- fix: Update Factory pull request branches (#13831) (`b670754`)
- chore: Add operator chat model selector (#13833) (`bb2fcb3`)
- fix: Move model selector to workspace creation (#13835) (`72805d7`)
- chore: Skip redundant Factory PR approval (#13837) (`bbe5406`)
- chore: Use geistdocs 1.23.1 (#13834) (`3787c06`)
- chore: Handle feedback on Factory pull requests (#13836) (`a76330b`)
- fix: Escape ampersands in RSS feed enclosure URLs (#13839) (`7107f26`)
- chore: Add automatic issue handling (#13840) (`e1674e4`)
- chore: Alert Slack for low-confidence issues (#13841) (`f153cda`)
- feat: Require high confidence for issue fixes (#13842) (`c97782b`)
- fix: Run pnpm directly on Windows (#13843) (`9d2b03b`)
- chore: Release Turborepo 2.10.12 (#13844) (`32748f5`)
- fix: Remove unsupported remote cache environment variable (#13845)
(`b4c2eed`)
- fix: Copy TUI selections locally over SSH (#13847) (`03df632`)
- feat: Use uv workspace metadata (#13848) (`fa1ca7d`)
- feat: Support Python virtual environments (#13849) (`7f66dbd`)
- fix: Scope uv lockfile affectedness (#13850) (`1e074f3`)
- test: Isolate uv prune configuration (#13851) (`9f2fd33`)
- fix: Explain disabled uv task caching (#13852) (`0f59d11`)
- fix: Explain uv identity probe failures (#13853) (`eabe73a`)
- fix: Explain uncached Cargo library builds (#13855) (`35ce2fa`)
- fix: Explain disabled Cargo task caching (#13854) (`39821f6`)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

This branch was successfully deployed

1 active deployment
Preview – turborepo-factory — 6c431731 Deployed Aug 20, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant