pnpm 12 audit is CPU-bound, not network-bound
pnpm audit got ~60x slower in 12.x and the fix starts with checking user CPU time, not the registry.
After upgrading to pnpm 12.3.4, pnpm audit jumped from ~2.8s to ~178s in CI. The wall time was user CPU rather than network latency, spent in the single-threaded native binary that bin/pnpm.mjs spawnSyncs (@pnpm/exe.<platform>/pnpm).
Note
Tested with pnpm 11.25.0 and pnpm 12.3.4 on macOS (arm64) on 2026-09-07.
What I Learned
Comparing wall versus user time on the same lockfile shows the shift:
/usr/bin/time pnpm@11.25.0 audit --prod --audit-level high
# real 0.73s user 0.38s
/usr/bin/time pnpm@12.3.4 audit --prod --audit-level high
# real 32.00s user 31.39s ← CPU-bound, not I/O
User ≈ real means the process is computing, not waiting on the network. ps confirms one core pinned at 100% in the native child while the Node shim idles in kevent.
Bisecting by pruning importer dep edges from a copy of the lockfile (edges out, never entries (deleting packages:/snapshots: entries breaks lockfile references)) produced a minimal repro: one importer dep, expo-dev-client, same lockfile, same machine.
# lockfile with a single dependency: expo-dev-client
pnpm@11.25.0 audit --prod --audit-level high # 0.73s
pnpm@12.3.4 audit --prod --audit-level high # 9.61s, 100% of one core
With all 83 of that importer’s dependencies restored, the same file takes 0.67s on 11.25.0 and 31.61s on 12.3.4. --json narrows the trigger further: pnpm 12 is only slow when an advisory actually matches (metadata.vulnerabilities.moderate: 1 for expo-dev-client). No match, fast. Match, and it enumerates dependency paths for the finding through the whole graph (expo-dev-client resolves to 730 total deps, 272 optional), the same diamond-path behavior documented in pnpm issue #12086, whose fix landed in 11.5.1/11.9.0.
Notes
--loglevel debugand--reporter ndjsonprint nothing per-phase for audit; the native binary also ignoresNODE_OPTIONS, so--cpu-profdies at the shim.- Next diagnostic step when the binary hides the JS: run the CLI from the pnpm repo source under
node --cpu-prof. - An earlier per-dep timing of mine flagged
@powersync/react-nativeas a second heavy dep; repeated runs showed it fast on both majors (0.34s to 0.47s). Verify anomalous timings before building a story on them.
References
- pnpm audit docs: flags include
--audit-leveland--reporter - pnpm#12086: prior CPU-bound audit regression, v11 rewrite
- pnpm#12467: Tarjan SCC fix shipped in 11.9.0
This post was written with AI assistance.