Dependency caching reference
Find information on the functionality of dependency caching in workflows.
In this article
cache
action usage
Thecache
action will attempt the following sequence when restoring a cache:
- First, it searches for an exact match to your provided
key
. - If no exact match is found, it will search for partial matches of the
key
. - If there is still no match found, and you've provided
restore-keys
, these keys will be checked sequentially for partial matches. For more information, seeCache key matching.
If there is an exact match to the providedkey
, this is considered a cache hit. If no cache exactly matches the providedkey
, this is considered a cache miss. On a cache miss, the action automatically creates a new cache if the job completes successfully. The new cache will use thekey
you provided and contains the files you specify inpath
. For more information about how this is handled, seeCache hits and misses.
You cannot change the contents of an existing cache. Instead, you can create a new cache with a new key.
Input parameters for thecache
action
key
:Required The key created when saving a cache and the key used to search for a cache. It can be any combination of variables, context values, static strings, and functions. Keys have a maximum length of 512 characters, and keys longer than the maximum length will cause the action to fail.path
:Required The path(s) on the runner to cache or restore.You can specify a single path, or you can add multiple paths on separate lines. For example:
-name:CacheGradlepackagesuses:actions/cache@v4with:path:| ~/.gradle/caches ~/.gradle/wrapper
You can specify either directories or single files, and glob patterns are supported.
You can specify absolute paths, or paths relative to the workspace directory.
restore-keys
:Optional A string containing alternative restore keys, with each restore key placed on a new line. If no cache hit occurs forkey
, these restore keys are used sequentially in the order provided to find and restore a cache. For example:restore-keys:| npm-feature-${{ hashFiles('package-lock.json') }} npm-feature- npm-
enableCrossOsArchive
:Optional A boolean value that when enabled, allows Windows runners to save or restore caches independent of the operating system the cache was created on. If this parameter is not set, it defaults tofalse
. For more information, seeCross OS cache in the Actions Cache documentation.
Note
We recommend that you don't store any sensitive information, such as access tokens or login credentials, in files in the cache path. Anyone with read access can create a pull request on a repository and access the contents of a cache. Additionally, forks of a repository can create pull requests on the base branch and access caches on the base branch.
Output parameters for thecache
action
cache-hit
: A boolean value to indicate an exact match was found for the key.
Cache hits and misses
Whenkey
exactly matches an existing cache, it's called acache hit, and the action restores the cached files to thepath
directory.
Whenkey
doesn't match an existing cache, it's called acache miss, and a new cache is automatically created if the job completes successfully.
When a cache miss occurs, the action also searches your specifiedrestore-keys
for any matches:
- If you provide
restore-keys
, thecache
action sequentially searches for any caches that match the list ofrestore-keys
.- When there is an exact match, the action restores the files in the cache to the
path
directory. - If there are no exact matches, the action searches for partial matches of the restore keys. When the action finds a partial match, the most recent cache is restored to the
path
directory.
- When there is an exact match, the action restores the files in the cache to the
- The
cache
action completes and the next step in the job runs. - If the job completes successfully, the action automatically creates a new cache with the contents of the
path
directory.
For a more detailed explanation of the cache matching process, seeCache key matching.
Example using thecache
action
This example creates a new cache when the packages inpackage-lock.json
file change, or when the runner's operating system changes. The cache key uses contexts and expressions to generate a key that includes the runner's operating system and a SHA-256 hash of thepackage-lock.json
file.
name: Caching with npmon: pushjobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - name: Cache node modules id: cache-npm uses: actions/cache@v4 env: cache-name: cache-node-modules with: # npm cache files are stored in `~/.npm` on Linux/macOS path: ~/.npm key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build- ${{ runner.os }}- - if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }} name: List the state of node modules continue-on-error: true run: npm list - name: Install dependencies run: npm install - name: Build run: npm run build - name: Test run: npm test
name:Cachingwithnpmon:pushjobs:build:runs-on:ubuntu-lateststeps:-uses:actions/checkout@v5-name:Cachenodemodulesid:cache-npmuses:actions/cache@v4env:cache-name:cache-node-moduleswith:# npm cache files are stored in `~/.npm` on Linux/macOSpath:~/.npmkey:${{runner.os}}-build-${{env.cache-name}}-${{hashFiles('**/package-lock.json')}}restore-keys:| ${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build- ${{ runner.os }}--if:${{steps.cache-npm.outputs.cache-hit!='true'}}name:Listthestateofnodemodulescontinue-on-error:truerun:npmlist-name:Installdependenciesrun:npminstall-name:Buildrun:npmrunbuild-name:Testrun:npmtest
Using contexts to create cache keys
A cache key can include any of the contexts, functions, literals, and operators supported by GitHub Actions. For more information, seeContexts reference andEvaluate expressions in workflows and actions.
Using expressions to create akey
allows you to automatically create a new cache when dependencies change.
For example, you can create akey
using an expression that calculates the hash of an npmpackage-lock.json
file. So, when the dependencies that make up thepackage-lock.json
file change, the cache key changes and a new cache is automatically created.
npm-${{hashFiles('package-lock.json')}}
GitHub evaluates the expressionhash "package-lock.json"
to derive the finalkey
.
npm-d5ea0750
Using the output of thecache
action
You can use the output of thecache
action to do something based on whether a cache hit or miss occurred. When an exact match is found for a cache for the specifiedkey
, thecache-hit
output is set totrue
.
In the example workflow above, there is a step that lists the state of the Node modules if a cache miss occurred:
-if:${{steps.cache-npm.outputs.cache-hit!='true'}}name:Listthestateofnodemodulescontinue-on-error:truerun:npmlist
Cache key matching
Thecache
action first searches for cache hits forkey
and the cacheversion in the branch containing the workflow run. If there is no hit, it searches for prefix-matches forkey
, and if there is still no hit, it searches forrestore-keys
and theversion. If there are still no hits in the current branch, thecache
action retries the same steps on the default branch. Please note that the scope restrictions apply during the search. For more information, seeRestrictions for accessing a cache.
Cache version is a way to stamp a cache with metadata of thepath
and the compression tool used while creating the cache. This ensures that the consuming workflow run uniquely matches a cache it can actually decompress and use. For more information, seeCache Version in the Actions Cache documentation.
restore-keys
allows you to specify a list of alternate restore keys to use when there is a cache miss onkey
. You can create multiple restore keys ordered from the most specific to least specific. Thecache
action searches therestore-keys
in sequential order. When a key doesn't match directly, the action searches for keys prefixed with the restore key. If there are multiple partial matches for a restore key, the action returns the most recently created cache.
Example using multiple restore keys
restore-keys:| npm-feature-${{ hashFiles('package-lock.json') }} npm-feature- npm-
The runner evaluates the expressions, which resolve to theserestore-keys
:
restore-keys:| npm-feature-d5ea0750 npm-feature- npm-
The restore keynpm-feature-
matches any key that starts with the stringnpm-feature-
. For example, both of the keysnpm-feature-fd3052de
andnpm-feature-a9b253ff
match the restore key. The cache with the most recent creation date would be used. The keys in this example are searched in the following order:
npm-feature-d5ea0750
matches a specific hash.npm-feature-
matches cache keys prefixed withnpm-feature-
.npm-
matches any keys prefixed withnpm-
.
Example of search priority
key:npm-feature-d5ea0750restore-keys:| npm-feature- npm-
For example, if a pull request contains afeature
branch and targets the default branch (main
), the action searches forkey
andrestore-keys
in the following order:
- Key
npm-feature-d5ea0750
in thefeature
branch - Key
npm-feature-
in thefeature
branch - Key
npm-
in thefeature
branch - Key
npm-feature-d5ea0750
in themain
branch - Key
npm-feature-
in themain
branch - Key
npm-
in themain
branch
setup-*
actions for specific package managers
If you are caching the package managers listed below, using their respective setup-* actions requires minimal configuration and will create and restore dependency caches for you.
Package managers | setup-* action for caching |
---|---|
npm, Yarn, pnpm | setup-node |
pip, pipenv, Poetry | setup-python |
Gradle, Maven | setup-java |
RubyGems | setup-ruby |
Gogo.sum | setup-go |
.NET NuGet | setup-dotnet |
Restrictions for accessing a cache
Access restrictions provide cache isolation and security by creating a logical boundary between different branches or tags.Workflow runs can restore caches created in either the current branch or the default branch (usuallymain
). If a workflow run is triggered for a pull request, it can also restore caches created in the base branch, including base branches of forked repositories. For example, if the branchfeature-b
has the base branchfeature-a
, a workflow run triggered on a pull request would have access to caches created in the defaultmain
branch, the basefeature-a
branch, and the currentfeature-b
branch.
Workflow runs cannot restore caches created for child branches or sibling branches. For example, a cache created for the childfeature-b
branch would not be accessible to a workflow run triggered on the parentmain
branch. Similarly, a cache created for thefeature-a
branch with the basemain
would not be accessible to its siblingfeature-c
branch with the basemain
. Workflow runs also cannot restore caches created for different tag names. For example, a cache created for the tagrelease-a
with the basemain
would not be accessible to a workflow run triggered for the tagrelease-b
with the basemain
.
When a cache is created by a workflow run triggered on a pull request, the cache is created for the merge ref (refs/pull/.../merge
). Because of this, the cache will have a limited scope and can only be restored by re-runs of the pull request. It cannot be restored by the base branch or other pull requests targeting that base branch.
Multiple workflow runs in a repository can share caches. A cache created for a branch in a workflow run can be accessed and restored from another workflow run for the same repository and branch.
Usage limits and eviction policy
GitHub will remove any cache entries that have not been accessed in over 7 days. There is no limit on the number of caches you can store, but the total size of all caches in a repository is limited to 10 GB. Once a repository has reached its maximum cache storage, the cache eviction policy will create space by deleting the caches in order of last access date, from oldest to most recent.
If you exceed the limit, GitHub will save the new cache but will begin evicting caches until the total size is less than the repository limit. The cache eviction process may cause cache thrashing, where caches are created and deleted at a high frequency. To reduce this, you can review the caches for a repository and take corrective steps, such as removing caching from specific workflows. SeeManaging caches.
Next steps
To manage your dependency caches, seeManaging caches.