pnpm install is slow in GitHub Actions
A slow pnpm install in GitHub Actions almost always means the pnpm store is not being cached or restored, not that pnpm itself is slow. Check cache configuration and setup order first, then look for the same install running more than once across jobs.
AI agents find the cause
StarSling agents run this diagnosis against your workflows and run history, identify which cause is yours, and open the fix as a reviewable PR.
Symptoms
pnpm's speed claim rests on a content-addressable store that it can restore from a cache instead of downloading every package fresh, and every one of the causes below is a different way that restore fails to happen. The most common failure is caching node_modules or nothing at all instead of the pnpm store path, since the store and node_modules are different directories with different content and only the store is cache-worthy across installs. The next most common is running pnpm/action-setup after actions/setup-node, which breaks the cache key computation setup-node needs before pnpm exists on the runner. After caching is confirmed correct, check whether the workflow installs dependencies more than once, either in the same job through a stray duplicate step or across multiple jobs that each run a full install instead of sharing one. These four causes are ordered by how often a slow install traces back to them: store caching first, then general dependency caching gaps, then duplicate installs within a workflow, then duplicated setup across jobs.
The install step in the Actions log takes several minutes even though the same
pnpm installfinishes in seconds on your machine.The cache step in the workflow log reports a cache miss on every run, or there is no cache step for pnpm at all.
Multiple jobs in the same workflow each run their own
pnpm install, and the total install time scales with the number of jobs.You see
pnpm installinvoked more than once inside a single job's step list.Switching runners or bumping the pnpm version made an install that used to be fast slow again.
How to diagnose it
Open the failing run in the GitHub Actions UI and expand the
pnpm installstep; note its wall-clock duration and whether a preceding cache step reportscache-hit: trueorfalse.Run
grep -rn 'pnpm/action-setup\|actions/setup-node' .github/workflows/<file>.ymland read the two matches in order; pnpm/action-setup must come first.Run
grep -n "cache:" .github/workflows/<file>.ymlto confirmcache: 'pnpm'is set on the setup-node step in the same job as the slow install.Run
grep -c 'pnpm install' .github/workflows/<file>.ymlto count total install invocations in the file, then check whether that count exceeds one per job.If the cache step shows a hit but the install is still slow, check for pnpm version drift:
jq -r '.packageManager // "unset"' package.jsonprints the version the repo pins, andgrep -rn -A2 'pnpm/action-setup' .github/workflows/prints the version each workflow installs. There is nopatternfield in package.json; the pinned version lives inpackageManager. If it printsunset, or a workflow pins a different major, jobs can build incompatible stores and miss each other's cache.Confirm the store path itself: run
pnpm store pathlocally and check that the cached path in the workflow'sactions/cachestep (or the implicit path used bycache: 'pnpm') matches it, not anode_modulespath.
Likely causes
Ordered by how often each one turns out to be the answer. Confirm a cause with its check before you change anything.
The pnpm store path isn't cached, or setup order breaks the cache
pnpm keeps a content-addressable store, separate from node_modules, that it can reuse across installs instead of re-downloading packages. If the workflow caches node_modules or nothing at all, that store never persists between runs, so every install refetches everything from the registry. This also fails silently when pnpm/action-setup runs after actions/setup-node, because setup-node needs pnpm already on the PATH to compute the store's cache key, so cache: 'pnpm' in setup-node has nothing to key against.
Fix: pnpm store cachingConfirm it
Run
grep -rn 'actions/setup-node\|pnpm/action-setup' .github/workflows/and confirm pnpm/action-setup appears before actions/setup-node in the step order, and that setup-node hascache: 'pnpm'set.No dependency cache action is configured at all
Some workflows install dependencies with no caching action present anywhere in the job, which means every run pays the full download and extraction cost with nothing to restore. This is distinct from the pnpm-store-specific misconfiguration above: here there may be no actions/cache or setup-node cache step for any ecosystem in the job, and in a matrix or sharded workflow the missing cache cost multiplies by every parallel job.
Fix: Dependency cachingConfirm it
Run
grep -rn 'actions/cache\|cache:' .github/workflows/across the workflow that runs the slow install and confirm a cache step actually exists for the job in question, not just for a different job in the same file.The same install runs more than once in the workflow
A workflow can have correct caching and still be slow if
pnpm installexecutes twice: once as a dedicated setup step and again inside a later step, often left over from a workaround for stale artifacts. Each additional invocation pays store-lookup and dependency-resolution time again even when nothing changed, and the second run is pure waste with no fix beyond removing it.Fix: Duplicate dependency installsConfirm it
Run
grep -oP '(?<=run: ).*install.*' .github/workflows/<file>.yml | sort | uniq -don the workflow to list any install command that appears more than once within the same job.Every job repeats checkout and install instead of sharing setup
When several jobs in one workflow each run their own checkout, pnpm/action-setup, and install sequence, the total install time scales with job count even if every individual cache hits cleanly, because the store restore, lockfile verification, and symlink construction under node_modules still happen once per job. This is the setup being duplicated across jobs, as opposed to duplicated within a single job's steps.
Fix: Duplicated job setupConfirm it
Run
grep -c 'pnpm install' .github/workflows/<file>.ymland compare it against the number of jobs defined in the file; if the count matches or exceeds the job count, look at whether any of those jobs could consume artifacts from a build job instead of installing independently.
Hand it to an agent
Hand this prompt to your coding agent (Claude Code, Cursor, and the like) to run this diagnosis against your repository and report which cause it found.
Diagnose why `pnpm install` is slow in this repository's GitHub Actions workflows. Do not change anything yet. First, run `grep -rn 'pnpm/action-setup\|actions/setup-node' .github/workflows/` and check whether pnpm/action-setup runs before actions/setup-node, and whether setup-node has `cache: 'pnpm'` set, in that order (ci.cache.pnpm-store). Second, run `grep -rn 'actions/cache\|cache:' .github/workflows/` and confirm a cache step exists at all for the job that runs the slow install (ci.cache.dependency-cache). Third, in the specific workflow file with the slow install, run `grep -oP '(?<=run: ).*install.*' <file> | sort | uniq -d` to find any install command repeated within one job (ci.cache.duplicate-installs). Fourth, count `pnpm install` occurrences against job count in that file to check for duplicated setup across jobs (ci.hygiene.duplicated-setup). Report which of these four causes you found evidence for, in the order checked, with the exact grep output backing each conclusion, before proposing any fix.Go further
Find the cause, fix them all, or keep them fixed.
You have the prompt that works out which cause applies. Here is how much further you can take it, each step doing more for you than the last.
Find the cause
Copy the diagnosis prompt above
Hand it to your coding agent to confirm which cause applies in your repo. It reports back what it found and changes nothing.
Fix them all, once
Install the ci-speedup skill
One prompt audits your whole repo against all 73 ci-speedup patterns (these 10 plus 63 more) and hands your agent every fix at once. Open source, MIT, runs locally.
Keep it fixed, forever
Install the StarSling GitHub App
Connect GitHub and the fixes stay applied as your CI evolves, with agents that keep inspecting your workflows and opening optimization PRs you review.
Sources
1pnpm: Continuous Integration (opens in new tab)
2actions/setup-node: caching global packages data (opens in new tab)
Last updated 2026-08-31