How to Warm Dependency Caches in CI
A cache only helps if it exists. Warming it from main means PRs never pay the cold-install tax.
GitHub Actions caches are scoped: a PR can read caches from its base branch but not from sibling branches. Build the cache on main so every PR inherits it.
Build the cache on the default branch
Run a scheduled or push-triggered job on main that installs dependencies and saves the cache. PRs then restore it.
Use restore-keys for partial hits
A fallback key lets a slightly stale cache restore and update incrementally instead of starting cold.
.github/workflows/ci.yml
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-Skip the cold start entirely
Warm-pool managed runners (like Latchkey) keep dependency layers hot across jobs, so even the first PR run starts warm instead of provisioning and downloading from scratch.
Key takeaways
- PRs can only read base-branch caches, so warm main.
- restore-keys give partial hits instead of cold starts.
- Warm-pool runners keep caches hot across jobs.
Related guides
How to Share CI Caches Across BranchesUnderstand GitHub Actions cache scoping and share dependency caches across branches by building on main and u…
How to Reduce Cold Starts in CICut CI cold-start time: warm dependency caches, prebuilt images, and warm-pool runners that skip the provisio…
How to Cache Dependencies in GitHub Actions (Every Ecosystem)Cache dependencies in GitHub Actions with actions/cache - correct keys and paths for npm, yarn, pnpm, pip, Ma…
How to Use a Remote Build Cache in CISet up a remote build cache for Bazel, Turborepo, Nx, or Gradle so CI and developer machines share compiled a…