Skip to content

perf: Reduce CPU overhead in turbo run hot path - #11947

Merged
anthonyshew merged 2 commits into
mainfrom
faster-and-faster
Feb 21, 2026
Merged

anthonyshew merged 2 commits into
mainfrom
faster-and-faster

Conversation

@anthonyshew

@anthonyshew anthonyshew commented Feb 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Several targeted optimizations to reduce CPU time in turbo run's critical path. These changes reduce allocations, eliminate redundant computation, and improve algorithmic complexity in per-package operations.

Per-function improvements (absolute self-time)

Function Repo Before After Change
calculate_task_hash large 101ms <1ms eliminated from top (cached)
walk_glob large 218ms 111ms -49%
calculate_task_hash medium 26ms 17ms -35%
walk_glob medium 41ms 29ms -30%
to_summary small 7ms 6ms -25%

Changes

  • Binary-search status lookups in RepoGitIndex: Status entries are now sorted at index build time. Per-package filtering uses partition_point for O(log N) range queries instead of O(N) linear scans. Matters when both package count and dirty-file count are large.

  • Precompute external dependency hashes per-package: get_external_deps_hash sorts transitive dependencies and hashes them. Previously this ran for every task. Now it runs once per package and is cached, since multiple tasks in the same package produce the same hash. TaskHashable.external_deps_hash changed from Option<String> to Option<&str> to avoid cloning from the cache.

  • Combined branch+SHA libgit2 lookup: to_summary previously opened the git repo twice (once for branch, once for SHA). Now a single Repository::open call retrieves both.

  • Reuse buffers in ls-tree and hash-object walks: The tree walk and hash-object loops now reuse a String path buffer and a [u8; 40] hex buffer instead of allocating per entry. Uses hex::encode_to_slice instead of git2::Oid::to_string.

Wall-clock caveat

These CPU improvements don't translate cleanly to wall-clock time in benchmarks because git status and git ls-tree via libgit2 dominate total runtime (30-80% of profiled duration) and have high I/O variance between runs. The functions we optimized are real work that runs on every turbo run, but measuring end-to-end improvement requires many runs to overcome the git I/O noise floor.

Testing

All existing tests pass. Added regression tests for:

  • Sorted status binary-search correctness (prefix boundary, delete handling, empty prefix)
  • External deps hash determinism, order-independence, and empty-set behavior
  • TaskHashTracker pre-sized HashMap behavior

@anthonyshew
anthonyshew requested a review from a team as a code owner February 21, 2026 02:03
@anthonyshew
anthonyshew requested review from tknickman and removed request for a team February 21, 2026 02:03
@vercel

vercel Bot commented Feb 21, 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, Comment, Open in v0 Feb 21, 2026 2:25am
examples-designsystem-docs Ready Ready Preview, Comment, Open in v0 Feb 21, 2026 2:25am
examples-gatsby-web Ready Ready Preview, Comment, Open in v0 Feb 21, 2026 2:25am
examples-kitchensink-blog Ready Ready Preview, Comment, Open in v0 Feb 21, 2026 2:25am
examples-nonmonorepo Ready Ready Preview, Comment, Open in v0 Feb 21, 2026 2:25am
examples-svelte-web Ready Ready Preview, Comment, Open in v0 Feb 21, 2026 2:25am
examples-tailwind-web Ready Ready Preview, Comment, Open in v0 Feb 21, 2026 2:25am
examples-vite-web Ready Ready Preview, Comment, Open in v0 Feb 21, 2026 2:25am
turbo-site Ready Ready Preview, Comment, Open in v0 Feb 21, 2026 2:25am
turborepo-agents Ready Ready Preview, Comment, Open in v0 Feb 21, 2026 2:25am
turborepo-test-coverage Ready Ready Preview, Comment, Open in v0 Feb 21, 2026 2:25am

@anthonyshew anthonyshew changed the title perf: Reduce CPU overhead in turbo run hot path perf: Reduce CPU overhead in turbo run hot path Feb 21, 2026
Eliminate fork+exec overhead for the three hottest git subprocess calls
in turbo run startup: WorktreeInfo::detect, git ls-tree, and git status.
Replace with in-process libgit2 equivalents (Repository::discover,
tree.walk, repo.statuses).

Also skip expensive TaskSummary construction and SCMState::get when
neither --dry nor --summarize is set, and use sorted Vec instead of
BTreeMap for ls-tree results for better cache locality.
@github-actions

github-actions Bot commented Feb 21, 2026 •

Copy link
Copy Markdown
Contributor

Coverage Report

Metric Coverage
Lines 75.14%
Functions 46.75%
Branches 0.00%

View full report

@anthonyshew
anthonyshew merged commit a0e90cb into main Feb 21, 2026
103 checks passed
@anthonyshew
anthonyshew deleted the faster-and-faster branch February 21, 2026 02:43
github-actions Bot added a commit that referenced this pull request Feb 21, 2026
## Release v2.8.11-canary.17

Versioned docs: https://v2-8-11-canary-17.turborepo.dev

### Changes

- release(turborepo): 2.8.11-canary.16 (#11944) (`037b7ba`)
- perf: Reduce CPU overhead in `turbo run` hot path (#11947) (`a0e90cb`)

---------

Co-authored-by: Turbobot <turbobot@vercel.com>

This branch was successfully deployed

2 active deployments
Preview – turborepo-agents — 28991ee2 Deployed Feb 21, 2026 by vercel[bot]
Preview – turborepo-test-coverage — 28991ee2 Deployed Feb 21, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant