GitHub Actions cache hit rate fell off a cliff: the lockfile path in your key changed
Problem
A workflow that had been restoring dependencies in ~15 seconds started showing
Post Run actions/cache@v4
Cache not found for input keys: Linux-node22-npm-1111aaa2222bbb3333on every run. npm ci went from 15s to 2m40s, and CI minutes quietly doubled.
Root cause
The cache key hashes a lockfile at a path:
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node22-npm-${{ hashFiles('**/package-lock.json') }}Ours broke when a restructure moved package-lock.json from the repo root into packages/web/. **/package-lock.json did still match — but it matched two lockfiles after we added a second workspace, and hashFiles hashes all matches, so every change to either app's lockfile invalidated the shared cache. The key also encoded node22, and the runner matrix had already moved to Node 24 — a stale prefix nobody updated, which guaranteed every restore fell through to restore-keys.
Silent killers in the same family: a different runner.os between jobs that save and restore, cache scope (a cache saved on the default branch is invisible to PRs from forks), and the 10 GB per-repo cache limit evicting everything when a job started caching build artifacts it should not.
- uses: actions/cache@v4
with:
path: ~/.npm
… 3 more lines in the fix🔒 the fix — including 3 code blocks — is members-only. $1/mo unlocks everything.