In your workflows, you can use different strategies to name your key depending on your use case so that the cache is scoped properly based on the need. If you wish to create OS specific caches, or caches based on the lockfiles, commit SHA, workflow run id, etc. then you can generate the keys dynamically at run-time. Below are some of the tips to strategically name your cache using the [cache](https://github.com/actions/cache) or [restore](https://github.com/actions/cache/tree/main/restore) action.
One of the most common use case is to use hash for lockfile as key. This way same cache will be restored for same lockfiles until there's any change in the lockfile/dependencies.
**Using restore keys to download the closest matching cache**
If cache is not found matching the primary key, restore keys will be used to download the closest matching cache that was recently created. This way most of the dependencies can be downloaded from the restore key hence saving some build time.
The restore keys can be provided as a complete name, or a prefix, read more [here](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key) on how a cache key is matched using restore keys.
Caches can be stored separately for different Operating Systems. This can be used in combination with hashfiles in case multiple caches are being generated per OS.
The [GitHub Context](https://docs.github.com/en/actions/learn-github-actions/contexts#github-context) can be used to create keys using the workflows metadata.
In case you are using a centralized job to create and save your cache that can be reused by other jobs in your repository, this action will take care of your restore only needs and make the cache read-only.
You can use the output of this action to exit the workflow on cache miss. This way you can restrict your workflow to only initiate the build when `cache-hit` occurs, in other words, cache with exact key is found.
There are instances where some flaky test cases would fail the entire workflow and users would get frustrated because the builds would run for hours and the cache couldn't get saved as the workflow failed in between. For such use-cases, users would now have the ability to use `actions/cache/save` action to save the cache by using `if: always()` condition. This way the cache will always be saved if generated, or a warning will be thrown that nothing is found on the cache path. Users can also use the `if` condition to only execute the `actions/cache/save` action depending on the output of the previous steps. This way they get more control on when to save the cache.
```yaml
steps:
- uses: actions/checkout@v3
.
. // restore if need be
.
- name: Build
run: /build.sh
- uses: actions/cache/save@v3
if: always() // or any other condition to invoke the save action
The [cache](https://github.com/actions/cache/tree/main#cache) action allows caching dependencies and restoring them using a single action. It has a `main` step and a `post` step. In the `main` step, the cache is restored if it exists for the input `key`, `path` combination (refer [scope](#scope)). If cache is not found for the given `key` input, then cache is restored using [restore keys](#restore-keys) . If the cache doesn't exist or is restored using `restore-keys`, the cache is saved in the `post` step of this action.
The `cache` action provides one output `cache-hit` which is set to `true` when cache is restored using primary key and `false` when cache is restored using `restore-keys` or no cache is restored.
In case of multi-module projects, where the built artifact of one project needs to be reused in subsequent child modules, the need of rebuilding the parent module again and again with every build can be eliminated. The `actions/cache` or `actions/cache/save` action can be used to build and save the parent module artifact once, and restored multiple times while building the child modules.