Skip to content

perf(plugin): batch hash computation in createNodesV2#866

Open
omer-za wants to merge 1 commit intoPhillip9587:mainfrom
omer-za:perf/batch-hash-computation
Open

perf(plugin): batch hash computation in createNodesV2#866
omer-za wants to merge 1 commit intoPhillip9587:mainfrom
omer-za:perf/batch-hash-computation

Conversation

@omer-za
Copy link

@omer-za omer-za commented Feb 27, 2026

Summary

Replace individual calculateHashForCreateNodes calls with a single batched calculateHashesForCreateNodes call in the createNodesV2 handler.

Currently, createNodesInternal calls calculateHashForCreateNodes individually for each config file. Under the hood, each call invokes hashWithWorkspaceContext separately — meaning N config files trigger N separate I/O-bound hash operations.

The @nx/devkit already exports a batch counterpart — calculateHashesForCreateNodes — which uses hashMultiGlobWithWorkspaceContext to batch all project root hashes into a single call.

This PR pre-computes all hashes upfront via the batch API and passes a hashByRoot map to createNodesInternal, falling back to the individual call for the deprecated createNodes v1 path.

Benchmark

Measured on a real monorepo with 251 stylelint config files across ~1,600 projects.

Before After Change
Cold run (avg of 3) ~4,130ms ~2,100ms -49%

Methodology

  • NX_DAEMON=false to prevent daemon caching
  • Stylelint plugin hash cache cleared between each cold run (find .nx -name "stylelint-*" -delete)
  • performance.now() instrumentation added around the createNodesV2 handler
  • Each measurement repeated 3 times, averaged

Changes

  • Import calculateHashesForCreateNodes alongside existing calculateHashForCreateNodes
  • In createNodesV2, compute all project root hashes upfront via the batch API
  • Pass pre-computed hashByRoot: Map<string, string> to createNodesInternal
  • createNodesInternal uses the map when available, falls back to individual hash for the v1 createNodes path
  • No behavior change: identical hash values, identical targets, identical caching

Made with Cursor

Replace individual `calculateHashForCreateNodes` calls with a single
batched `calculateHashesForCreateNodes` call. This uses
`hashMultiGlobWithWorkspaceContext` under the hood, which batches all
I/O operations into a single call instead of making N separate calls.

In large monorepos (250+ stylelint configs), the per-config hash
computation is a significant bottleneck during Nx graph calculation.

Made-with: Cursor
@omer-za
Copy link
Author

omer-za commented Feb 27, 2026

@Phillip9587 Can you please review it?

@nx-cloud
Copy link

nx-cloud bot commented Feb 27, 2026

View your CI Pipeline Execution ↗ for commit a972d9a

Command Status Duration Result
nx run e2e:e2e --configuration=ci ✅ Succeeded 2m 22s View ↗
nx build nx-stylelint ✅ Succeeded 1s View ↗
nx test nx-stylelint --ci ✅ Succeeded 8s View ↗
nx lint nx-stylelint ✅ Succeeded 2s View ↗

☁️ Nx Cloud last updated this comment at 2026-02-27 12:03:50 UTC

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