# GitHub Actions cache "Cache service responded with 429": how to recover

TL;DR: Your workflow is hammering the cache service with too many save or restore calls at once. Make most matrix legs restore-only so a single job saves, give each leg a distinct key, and retry the occasional transient 429. The build still works; it just runs uncached until the writes calm down.

```text
Warning: Failed to save: Cache service responded with 429
```

## Steps

1. Count who saves. If every leg of a 20-job matrix calls `actions/cache` with the same key, they all race to save at once. Switch all but one leg to `actions/cache/restore` and keep a single `actions/cache/save`, or use one dedicated priming job.
**Expected:** Cache writes drop from N per run to one per run.

2. Dedupe keys across the matrix. Include the matrix values and a hash of the lockfile in the key so legs are not fighting over one entry.
**Expected:** Each leg restores its own cache instead of stampeding a shared one.

3. Retry transient failures instead of failing the job. A lone 429 on restore is usually the service shedding load; rerun the failed job a few minutes later rather than the whole workflow.
**Expected:** The rerun restores cleanly.

4. Prune dead caches. Each repo gets 10 GB of cache and entries unused for 7 days are evicted automatically, but stale entries from renamed branches still eat budget. List and delete what you no longer need.
**Expected:** Cache usage drops well under the cap.

5. For heavy shared dependencies, run one scheduled priming workflow that saves the cache, and make every CI run restore-only.
**Expected:** CI never writes caches at all, so 429s stop appearing.

## Use this when
- `actions/cache` save or restore steps fail with `Cache service responded with 429`

## Not for this skill when
- The message is `Cache not found for input keys`. That is a miss, not a rate limit; fix the key
- Restores fail because the key changed. Different problem, same step
- The 429 comes from the artifact service or a registry. Those have their own limits and fixes

## Variant phrasings
### Failed to restore: Cache service responded with 429
Same throttle, on the read path; usually transient, retry the job.

### Cache service responded with 503
The service is unhealthy rather than throttling you; back off and retry.

## Why it happens
Saves are the expensive operation on the cache service, and GitHub throttles aggressive patterns: many parallel jobs saving the same key, or a workflow that saves on every push across dozens of branches. The throttle protects the service; your job is collateral.

## Edge cases
- Caches are scoped to the repo and fall back to the default branch; a new branch starts cold no matter what
- A cache entry is immutable once saved, so racing savers also waste effort even when they do not 429
- `fail-on-cache-miss` turns a miss into a failure; do not confuse that with throttling

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_0SHn1R_xtLXTBWuJ9nOhyw
