Verify latest release
pnpm version
No response
Which area(s) of pnpm are affected? (leave empty if unsure)
No response
Link to the code that reproduces this issue or a replay of the bug
No response
Reproduction steps
Reproduction
The public reproduction is here: https://github.com/jamenh/pnpm-workspace-performance-reproduction
It contains:
- 6,833 workspace projects
- 87,630 internal
workspace:* dependency edges
Clone the given repo above, then run
pnpm install --lockfile-only --frozen-lockfile --offline --reporter-ndjson
and
yarn install --mode update-lockfile
Test on a warmed, non-noop scenario (e.g. updating a dependecy and update lockfile again) to test resolution time.
Describe the Bug
Summary
This is a follow-up to #14151. Our earlier reproduction did not isolate the relevant scaling factors well enough. But this issue does.
We are evaluating pnpm for a large monorepo migration from Yarn. We benchmarked install and install --lockfile-only and pnpm 12 beats Yarn on install by a lot but it is slower on install --lockfile-only . On this representative reproduction, we are able to show that pnpm 12 is consistently slower than Yarn 4 for a lockfile-only update, and the gap grows as the repository scales. (This may not be a functional bug, we are filing this more as a performance issue since it isn't aligned with what's advertized. But feel free to redirect me to elsewhere.)
| Tools |
Warm Update - Scope |
Warm Update - Resolution |
Warm Update - Summary |
Warm Update - Wall |
| Yarn 4.18 |
N/A |
0.6 s |
N/A |
1.6 s |
| pnpm 12 |
3 s |
1.3 s |
5 s |
11 s |
Areas with clear optimization headroom
While investigating the reproduction, we found two areas that appear to have relatively direct optimization opportunities.
Workspace discovery
Large monorepos contain many directories that are not workspaces, such as examples/, stories/, fixtures/ and tests/. Recursive workspace patterns must traverse these directories, which makes workspace discovery slower.
We already use literal paths and one-level parent/* patterns wherever possible to avoid unnecessary recursive walks. However, pnpm currently still sends even these precise patterns through the generic wax glob walker. It also combines each pattern with every supported manifest name, repeating glob setup and directory work for every pattern.
We raised PR #14262 that explores fast paths for literal paths and one-level parent/* patterns to avoid the wax glob walker. On the reproduction, it reduces median workspace-scoping time from about 3.0 s to 0.84 s, a ~70% improvement.
Workspace dependency resolution
In a large monorepo, many projects depend on the same internal workspace packages. pnpm repeats much of the same resolution work for each importer, which makes installs and lockfile updates slower as the workspace grows.
The resolver cache key includes project_dir, which identifies the project that declares the dependency. Including it in the key basically prevents different projects from sharing the cached resolution.
We raised PR #14266 that separates the shared package resolution from the project-specific relative-link calculation. On the same reproduction, it reduces median resolution time from about 752 ms to 492 ms, improved ~35%.
The ask
If these directions are sound, please leave comments/feedback on PRs and we would be happy to drive them to completion. But please feel free to take a different routes if you think it'll address the underlying problems better, it's fine these particular PRs don't land as long as the problems are addressed. Our priority is being able to migrate(we can't when our Yarn 4 baseline still beats pnpm 12 on lockfile update).
Expected Behavior
Faster lockfile update.
Which Node.js version are you using?
24.11.1
Which operating systems have you used?
If your OS is a Linux based, which one it is? (Include the version if relevant)
No response
Verify latest release
pnpm version
No response
Which area(s) of pnpm are affected? (leave empty if unsure)
No response
Link to the code that reproduces this issue or a replay of the bug
No response
Reproduction steps
Reproduction
The public reproduction is here: https://github.com/jamenh/pnpm-workspace-performance-reproduction
It contains:
workspace:*dependency edgesClone the given repo above, then run
and
Test on a warmed, non-noop scenario (e.g. updating a dependecy and update lockfile again) to test resolution time.
Describe the Bug
Summary
This is a follow-up to #14151. Our earlier reproduction did not isolate the relevant scaling factors well enough. But this issue does.
We are evaluating pnpm for a large monorepo migration from Yarn. We benchmarked
installandinstall --lockfile-onlyand pnpm 12 beats Yarn oninstallby a lot but it is slower oninstall --lockfile-only. On this representative reproduction, we are able to show that pnpm 12 is consistently slower than Yarn 4 for a lockfile-only update, and the gap grows as the repository scales. (This may not be a functional bug, we are filing this more as a performance issue since it isn't aligned with what's advertized. But feel free to redirect me to elsewhere.)Areas with clear optimization headroom
While investigating the reproduction, we found two areas that appear to have relatively direct optimization opportunities.
Workspace discovery
Large monorepos contain many directories that are not workspaces, such as
examples/,stories/,fixtures/andtests/. Recursive workspace patterns must traverse these directories, which makes workspace discovery slower.We already use literal paths and one-level
parent/*patterns wherever possible to avoid unnecessary recursive walks. However, pnpm currently still sends even these precise patterns through the generic wax glob walker. It also combines each pattern with every supported manifest name, repeating glob setup and directory work for every pattern.We raised PR #14262 that explores fast paths for literal paths and one-level
parent/*patterns to avoid the wax glob walker. On the reproduction, it reduces median workspace-scoping time from about 3.0 s to 0.84 s, a ~70% improvement.Workspace dependency resolution
In a large monorepo, many projects depend on the same internal workspace packages. pnpm repeats much of the same resolution work for each importer, which makes installs and lockfile updates slower as the workspace grows.
The resolver cache key includes project_dir, which identifies the project that declares the dependency. Including it in the key basically prevents different projects from sharing the cached resolution.
We raised PR #14266 that separates the shared package resolution from the project-specific relative-link calculation. On the same reproduction, it reduces median resolution time from about 752 ms to 492 ms, improved ~35%.
The ask
If these directions are sound, please leave comments/feedback on PRs and we would be happy to drive them to completion. But please feel free to take a different routes if you think it'll address the underlying problems better, it's fine these particular PRs don't land as long as the problems are addressed. Our priority is being able to migrate(we can't when our Yarn 4 baseline still beats pnpm 12 on lockfile update).
Expected Behavior
Faster lockfile update.
Which Node.js version are you using?
24.11.1
Which operating systems have you used?
If your OS is a Linux based, which one it is? (Include the version if relevant)
No response