Skip to content

perf: Use Arc<str> for task dependency hashes to avoid heap clones#11962

Merged
anthonyshew merged 12 commits intomainfrom
perf/arc-str-dependency-hashes
Feb 22, 2026
Merged

perf: Use Arc<str> for task dependency hashes to avoid heap clones#11962
anthonyshew merged 12 commits intomainfrom
perf/arc-str-dependency-hashes

Conversation

@anthonyshew
Copy link
Copy Markdown
Contributor

@anthonyshew anthonyshew commented Feb 22, 2026

Summary

  • Store task hashes as Arc<str> in TaskHashTrackerState instead of String, so that calculate_dependency_hashes clones a ref-counted pointer (atomic increment) instead of heap-allocating a new String for each dependency hash lookup.

Why

queue_task is called once per task in the topological dispatch loop. For each task, calculate_dependency_hashes looks up every dependency's hash and clones it into a Vec. On large monorepos like api (1687 tasks, ~3 deps each), that's ~5000 String heap allocations per run — all for 16-char hex strings that are already stored in the tracker and never mutated.

Switching to Arc<str> makes each "clone" a pointer-width copy + atomic ref count increment instead of a heap allocation + memcpy.

Testing

  • All existing pinned-hash tests pass (the capnp serialization produces identical bytes since Arc<str> derefs to str).
  • Added task_hashable_multiple_dependency_hashes test with a pinned hash value to guard against serialization regressions.
  • Profiled on the our biggest repo (1039 packages, 1687 tasks): queue_task self-time dropped from ~208ms to ~193ms.

…very

Three targeted optimizations to the turbo run hot path:

1. Engine builder: Cache turbo.json chain per package and move the
   visited check before the expensive task_definition() call. The
   chain only depends on the package name, so multiple tasks in the
   same package reuse the cached result.

2. Task visitor: Defer env() computation to non-dry-run branches.
   The execution environment is unused during dry runs, avoiding
   per-task RwLock acquisition and env var map cloning.

3. find_untracked_files: Replace Mutex<Vec> with per-thread local
   buffers flushed via mpsc channel on drop, eliminating per-file
   mutex contention in the parallel walker.
Parallelize several sequential phases of turbo run's pre-execution
pipeline: dependency resolution, turbo.json loading, and task summary
construction. Also reduce per-call allocation overhead in the task
hash tracker and gix index classification.
…parallelize-hot-path

# Conflicts:
#	crates/turborepo-scm/src/repo_index.rs
Adds profiling visibility to functions that were invisible in
--profile output: TLS initialization, rayon-spawned hash tasks,
Visitor constructor, Engine scheduler, and per-task cache phases.
Store task hashes as Arc<str> in TaskHashTrackerState instead of String.
In calculate_dependency_hashes, cloning an Arc<str> is a ref count bump
instead of a heap allocation. For the api monorepo (1687 tasks, ~3 deps
each), this eliminates ~5000 String heap allocations per run.
@anthonyshew anthonyshew requested a review from a team as a code owner February 22, 2026 21:17
@anthonyshew anthonyshew requested review from tknickman and removed request for a team February 22, 2026 21:17
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Feb 22, 2026

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 22, 2026 9:26pm
examples-designsystem-docs Ready Ready Preview, Comment, Open in v0 Feb 22, 2026 9:26pm
examples-gatsby-web Ready Ready Preview, Comment, Open in v0 Feb 22, 2026 9:26pm
examples-kitchensink-blog Ready Ready Preview, Comment, Open in v0 Feb 22, 2026 9:26pm
examples-nonmonorepo Ready Ready Preview, Comment, Open in v0 Feb 22, 2026 9:26pm
examples-svelte-web Ready Ready Preview, Comment, Open in v0 Feb 22, 2026 9:26pm
examples-tailwind-web Ready Ready Preview, Comment, Open in v0 Feb 22, 2026 9:26pm
examples-vite-web Ready Ready Preview, Comment, Open in v0 Feb 22, 2026 9:26pm
turbo-site Ready Ready Preview, Comment, Open in v0 Feb 22, 2026 9:26pm
turborepo-agents Ready Ready Preview, Comment, Open in v0 Feb 22, 2026 9:26pm
turborepo-test-coverage Ready Ready Preview, Comment, Open in v0 Feb 22, 2026 9:26pm

@anthonyshew anthonyshew changed the title perf: Use Arc<str> for task dependency hashes to avoid heap clones perf: Use Arc<str> for task dependency hashes to avoid heap clones Feb 22, 2026
…Summary

Removes the .to_string() conversion in the HashTrackerInfo::hash() trait
impl by changing the trait return type from Option<String> to
Option<Arc<str>>. Also changes SharedTaskSummary.hash to Arc<str> so the
Arc flows all the way to serialization without any String allocation.
Copy link
Copy Markdown
Contributor

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Suggestion:

Missing explicit "rc" serde feature for Arc<str> serialization in turborepo-task-hash, relying on transitive feature activation from turborepo-lockfiles.

Fix on Vercel

The Arc<str> fields in TaskHashTrackerState and SharedTaskSummary
require serde's "rc" feature for Serialize. Previously this worked
via transitive feature activation; make it explicit so it doesn't
break if the transitive path changes.
@github-actions
Copy link
Copy Markdown
Contributor

Coverage Report

Metric Coverage
Lines 75.17%
Functions 46.86%
Branches 0.00%

View full report

@anthonyshew anthonyshew merged commit 56329a6 into main Feb 22, 2026
102 of 103 checks passed
@anthonyshew anthonyshew deleted the perf/arc-str-dependency-hashes branch February 22, 2026 21:42
github-actions Bot added a commit that referenced this pull request Feb 22, 2026
## Release v2.8.11-canary.22

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

### Changes

- release(turborepo): 2.8.11-canary.21 (#11961) (`83774bc`)
- perf: Use `Arc<str>` for task dependency hashes to avoid heap clones
(#11962) (`56329a6`)

---------

Co-authored-by: Turbobot <turbobot@vercel.com>
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