6.2.1. Cache and Retention Economics
💡 First Principle: Caches trade storage for time and are free but evictable; artifacts trade storage for access and are billed — so cache aggressively with well-chosen keys, and retain artifacts only as long as someone might actually download them.
Cache economics come down to hit rate. A good key changes only when the cached content should (hashFiles('**/package-lock.json')), with restore-keys prefixes providing a useful partial hit when it does change. Cache the dependency store rather than the installed tree where possible (~/.npm, ~/.m2, ~/.cargo), and remember the scoping rule from 2.3.1: default-branch caches are readable by all branches, so warming on main is what makes the first run of a new feature branch fast. Limits shape strategy: 10 GB per repository with least-recently-used eviction, and entries removed after 7 days without a hit.
Artifact economics are simpler and more often mismanaged. The default retention is 90 days, which is wildly longer than anyone needs for per-PR build outputs. Setting retention-days: 3 on noisy artifacts, and configuring a lower default at the repository or organization level, is usually the single biggest storage win. The objectives call out doing this programmatically, so know that retention defaults are settable through the Actions permissions API, and that DELETE /repos/{owner}/{repo}/actions/artifacts/{artifact_id} reclaims space immediately — the basis for a scheduled cleanup workflow.
| Lever | Mechanism | Typical impact |
|---|---|---|
| Dependency caching | actions/cache with a lockfile-hash key | Minutes per job |
| Warm cache on default branch | Run the cache-populating job on main | Fast first run on new branches |
| Shorter artifact retention | retention-days: + org/repo default | Direct storage bill |
| Scheduled artifact cleanup | DELETE .../artifacts/{id} on a schedule | Reclaims accumulated storage |
| Docker layer caching | Registry cache or cache-from/cache-to | Large for container builds |
⚠️ Exam Trap: Cache storage is free but capped and evictable; artifact storage is billed and retained. Never use a cache for something you must have later (a release binary, a compliance log) — it can disappear at any time with no error, and the run will simply rebuild or fail downstream.
Reflection Question: Your repository has a 9.8 GB cache footprint and a team complaining that caches "randomly disappear." Explain the mechanism, and give two changes that fix it without giving up caching.