Skip to content

pnpm audit is ~6x slower in 11.5.1+ than 11.4.0 on a large monorepo #12212

Description

@kpman

Last pnpm version that worked

11.4.0

pnpm version

11.5.1 and 11.5.2

Code to reproduce the issue

I can reproduce this on a large private pnpm workspace by timing pnpm audit with the same lockfile and the same Node.js version.

/usr/bin/time -p env COREPACK_HOME=/tmp/pnpm-corepack-cache corepack pnpm@11.4.0 audit
/usr/bin/time -p env COREPACK_HOME=/tmp/pnpm-corepack-cache corepack pnpm@11.5.1 --pm-on-fail=ignore audit
/usr/bin/time -p env COREPACK_HOME=/tmp/pnpm-corepack-cache corepack pnpm@11.5.2 --pm-on-fail=ignore audit

The --pm-on-fail=ignore flag is only used for 11.5.x because the workspace's packageManager field is pinned to pnpm@11.4.0; it lets the newer pnpm versions run without editing any project files. The commands were run sequentially, not in parallel, with the same Corepack cache.

Unfortunately I cannot share the private lockfile publicly, but the monorepo is a pnpm workspace with many packages and a fairly large dependency graph.

Expected behavior

pnpm audit in 11.5.1 and 11.5.2 should be roughly comparable to 11.4.0, or faster, especially since 11.5.1 includes the audit path traversal performance improvement from #12087.

Actual behavior

11.5.1 and 11.5.2 are about 6x slower than 11.4.0 on this lockfile. The audit output is otherwise equivalent: all three runs report the same 18 vulnerabilities (1 low | 9 moderate | 8 high).

pnpm version   real       user       sys
11.4.0         31.36s     29.95s     0.30s
11.5.1         183.06s    179.12s    1.48s
11.5.2         189.21s    184.64s    1.58s

The user time being very close to real time makes this look CPU-bound rather than registry/network-bound.

Additional information

I saw #12086 and #12087 while investigating this. This looks like it may be a lockfile-shape-specific counterexample to the #12087 optimization: the new reachability/saturation pruning seems to help the reported monorepo in #12086 a lot, but on this lockfile the added local traversal/reachability work appears to cost more than it saves.

I checked the bundled CLI code in the Corepack cache and confirmed that 11.5.1/11.5.2 include createReachableVulnerabilitiesGetter() and allReachableVulnerabilitiesSaturated(), while 11.4.0 does not.

Happy to run additional diagnostics or provide anonymized lockfile graph statistics if that would help narrow this down.

Node.js version

v24.16.0

Operating System

macOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions