Introduction
GitHub Actions caching speeds up builds, but large caches eventually fail to save. The usual cause is trying to cache heavyweight directories such as node_modules, generated build trees, or language toolchains wholesale. When cache archives grow too large, the save step warns or fails and subsequent workflows lose the expected cache benefit.
Symptoms
- The post-job cache save step warns that the cache exceeded the allowed size
- Builds become slower because cache restore works inconsistently or not at all
- Repository cache storage keeps growing even when dependency changes are small
- Teams cache whole dependency directories instead of package manager download caches
Common Causes
node_modules,.venv, or other bulky runtime directories are cached directly- One cache key is reused for too many unrelated files
- Old caches accumulate without cleanup or natural churn
- Build outputs and dependency caches are mixed into one archive
Step-by-Step Fix
- 1.Cache package manager artifacts, not full install directories
- 2.Package manager caches are usually much smaller and more stable than installed dependency trees.
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm- 1.Split caches by purpose
- 2.Keep dependency caches separate from framework build caches so one fast-changing directory does not bloat everything else.
- uses: actions/cache@v4
with:
path: .next/cache
key: nextjs-${{ hashFiles('package-lock.json') }}- 1.Remove stale or oversized caches
- 2.If the repository cache store is already bloated, cleanup may be required before the new strategy becomes effective.
- 3.Measure what is actually being cached
- 4.Check directory sizes before adding them to cache configuration. Many teams never validate the archive size until the save step fails.
Prevention
- Prefer built-in language cache features from setup actions where available
- Avoid caching full install trees unless you have a very specific reason
- Separate dependency caches from generated build artifacts
- Review cache growth periodically instead of waiting for save failures