GitHub Actions cache, explained
The GitHub Actions cache saves files between workflow runs, so a job doesn't download the same things again. You turn it on with the actions/cache step: a key names the cache, and a path says what to save.
What the GitHub Actions cache does
Every job on a GitHub-hosted runner starts on a clean machine. So each run fetches your packages again: npm modules, Go modules, pip wheels and more. That takes time.
GitHub Actions caching fixes part of that. At the end of a job, the cache step uploads a folder to GitHub. The next run downloads it back before your build starts. A download of one big file is often faster than many small installs.
Here is a simple cache step with actions/cache v4:
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-
Many setup actions can do this for you. For example, actions/setup-node has a cache: npm input.
Cache only what is slow to make and safe to share. Good choices are package downloads and build tool caches. Don't cache secrets, and don't cache your build output if you need a clean build each time.
How cache keys and restore-keys work
The key is the cache's name. Put a hash of your lock file in it. When the lock file changes, the key changes, and a new cache is saved.
The steps run in this order:
Exact match
GitHub looks for a cache with the exact key. If found, it is a hit.
Prefix match
If not, it tries each
restore-keysprefix in order. It takes the newest cache that matches.Save
If there was no exact hit, the step saves a new cache under the full key when the job ends.
Caches are also tied to branches. A run can restore caches from its own branch and the default branch. A pull request can also use its base branch. It can't use a cache made on a sibling branch.
Cache limits and eviction
GitHub caps the cache for each repo. As of November 2026, the default is 10 GB per repo, and admins can raise it. When the repo is full, GitHub deletes the caches that were used longest ago first. It also removes any cache entry not used in over 7 days.
These numbers change. Check GitHub's caching docs for today's limit.
Why your cache misses
A miss means the job does the full install again. Common causes:
- The key changed. A new lock file hash, OS or tool version makes a new key.
- Wrong branch. A feature branch can't see a cache saved on another feature branch.
- It was evicted. Big caches push old ones out. Unused ones expire after 7 days.
- The job failed. The cache step saves at the end, so a failed job may save nothing.
- Wrong path. The
pathmust match where the tool really writes files.
A cache that hits can still be slow. Uploading and downloading a large file takes time on every run. If your builds still drag, see why GitHub Actions is slow.
How to clear the cache
Sometimes a cache goes bad, and you want a clean build. There are two ways to clear the GitHub Actions cache.
- On GitHub. Open your repo, go to the Actions tab, then Caches in the sidebar. Delete the entries you don't want.
- From the command line. Use the GitHub CLI:
gh cache list
gh cache delete npm-Linux-1a2b3c # one cache, by key
gh cache delete --all # every cache in the repo
A quick trick also works: add -v2 to your key. Old caches no longer match, and they expire on their own.
A local cache on your own machine
On a self-hosted runner, the job runs on your computer. actions/cache works there as well. But your machine can also keep files close by, with no upload at all.
Codemany gives each job a fresh, single-use runner on your Mac or Linux machine. Some things still stay warm between jobs:
- Tool cache. Downloads from
actions/setup-go,setup-node,setup-pythonand otheractions/setup-*steps stay in~/.codemany/toolcache. It is pruned past 20 GB. - Go modules on Linux. Jobs get a
GOPROXYthat points at a mirror on the machine. If the mirror is down, Go falls back to proxy.golang.org. - Docker Hub on Linux. BuildKit's Docker Hub pulls go to a local mirror first. Read Docker layer caching in GitHub Actions.
Your own settings always win. If your workflow sets GOPROXY, Codemany leaves it alone. More on this in local cache.
Questions
How big can the GitHub Actions cache be?
GitHub caps it per repo and evicts old entries. Check GitHub's docs for today's limit.
How do I clear the GitHub Actions cache?
Delete entries in the repo's Actions › Caches page, or with the gh cache delete command.
Does actions/cache work on self-hosted runners?
Yes. On Codemany, the tool cache also stays warm on the machine, and Linux machines keep local package mirrors.
Related
Read next: local cache, Docker layer caching, slow GitHub Actions and what a self-hosted runner is.
Start a 14-day trial No card needed. $20 a month for 2 machines after that.