Skip to main content
Cache Volumes are NVMe-backed storage attached to your runner instances that persist data across GitHub Actions runs. They are the primitive that every caching feature in this section builds on: container image pulls, git checkouts, toolchain downloads, action archives, and build-system caches are all applications layered on top of the same volume infrastructure. For the underlying architecture, see Cache Volumes in the storage documentation.

Choosing a caching solution

You have three options to cache your workflow data with Namespace. Pick based on how much workflow change you can tolerate and how predictable you need cache hits to be:

GitHub Actions Cache

Works out of the box with no workflow changes. Best when you want a drop-in solution and the default behavior is good enough.

Namespace Cache Volumes

Fully local NVMe storage with high IOPS and no upload/download time. Best for the fastest cache hits; expect occasional misses on early runs. Requires small workflow changes.

Namespace Artifacts

Consistent cache hits from the first run, with explicit control over content and lifecycle. Best for expensive build outputs shared across jobs. Requires workflow changes.
There is a ramp-up period when starting to use Cache Volumes, where cache hits will be lower until there is enough distribution of your data. The more jobs you run, the better the cache hit ratio will get. Learn more about Cache Volume onboarding.

Using a cache volume

Cache Volumes attach to a runner and expose a persistent directory that survives across runs. Unlike traditional caching solutions that require time-consuming uploads and downloads, Cache Volumes provide instant access to cached data through guaranteed cache locality. Cache Volumes support very high concurrency through automatic forking and scale up to hundreds of GB to match your project needs.
1

Enable caching on your Runner Profile

Open the desired Runner Profile and enable caching. The minimum cache size is 20 GB.
runner profile cache configuration
Enabling Cache Volumes turns on caching for the built-in software layers. Each layer has its own sub-toggle in the profile so you can narrow what is cached: Container images, Git checkouts, Toolchains, and Actions.
2

Use the cache in your workflow

The simplest way to start using the cache is to adopt nscloud-cache-action. The action supports many popular frameworks natively, but can also be used to cache arbitrary files or directories.
  1. Add the action to your workflow and select which framework you use. You can enable caching for multiple frameworks simultaneously:
    For a full list of supported frameworks, check out the action reference.
  2. In case native support is not available yet, you can still make your framework work with Cache Volumes. Simply configure a list of paths to retain:
    Our support team can help you identify the optimal cache configuration.
3

Skip GitHub's action cache

After enrolling Namespace’s caching, disable GitHub’s builtin action caching. This ensures that you avoid any superfluous network transfers, reducing the setup time of your workflow further.
If your jobs run inside a container, you also need to mount the cache volume inside the container. See Running jobs in containers.

What you can cache

The caching features below all use Cache Volumes.

Container Images

Cache container image layers and the often expensive unpacking step, so repeated pulls complete in seconds. See Container Images.

Git Checkouts

Cache a mirror of your git repository to speed up checkouts of large repositories, submodules, and Git LFS objects. See Git Checkouts.

Toolchain Downloads

Cache downloads from setup actions like actions/setup-go, actions/setup-python, and actions/setup-node. See Toolchains.

Action Downloads

Cache the action archives your job downloads at startup, and use nscloud-cache-action as an actions/cache replacement. See Actions.

Build System Integrations

Native caching presets for Bazel, Turborepo, Pants, Moonrepo, Gradle, and sccache. See Build System Integrations.

Advanced cache volume management

Namespace cache volumes are separated at multiple levels to ensure security and prevent data leakage between different contexts.

Isolation levels

Workspace isolation: Each workspace maintains completely separate cache volumes. Caches from one workspace cannot be accessed by any other workspace, providing a strong security boundary between different organizational units or projects. Runner Profiles: Different runner profiles use distinct cache volumes, even within the same workspace. This ensures that builds running on different profiles don’t interfere with each other’s cached data by default. Sharing the cache between two profiles is possible. Repository: Each repository using a specific runner profile gets its own separate cache volume. The cache volume will be shared between all jobs running for a Git repository, but remains distinct from other repositories, even when they share the same runner profile configuration. Sharing the cache between two repositories is possible. For scenarios requiring more control over the cache isolation boundary, custom cache tags can be specified.

Sharing a cache volume

By default, Namespace isolates cache volumes. Each runner profile gets its own cache volume, and within a profile each repository gets its own too. Use a custom cache tag to have several jobs, profiles, or repositories reuse one cache. Every job that resolves to the same tag within a workspace attaches to the same cache volume. Append ;overrides.cache-tag={tag} to the profile name. Two different profiles that set the same tag share one cache volume:
namespace-profile-builds and namespace-profile-e2e-tests are separate profiles with their own machine shapes and features, but both jobs read and write the same my-shared-cache volume. This also works across repositories: any repository whose jobs set overrides.cache-tag=my-shared-cache joins the same cache. Every job sharing the tag can also update the cache contents. To let some of them read the cache without persisting their changes, see Protect caches from updates.

Custom cache identity

For scenarios requiring full control over the cache isolation boundary, you can specify custom cache tags. To specify a custom cache tag when using a profile, append ;overrides.cache-tag=new-tag-value to the profile name:
Because every job resolving to the same cache tag attaches to the same volume, this is also how you share a cache across profiles or repositories. See Sharing a cache volume.

Protect caches from updates

You can configure Cache Volumes to limit what git branches can perform updates to them. Restricting the source of cache updates is useful to avoid cache poisoning. When using this feature, all branches (including pull requests) can benefit from your cache, but only selected branches (e.g. main) may commit changes to it. To specify which branches can update the cache volume, open the cache volume configuration, then check Show Advanced features, and finally type the branch names.
branch cache configuration
Any GitHub Actions job belonging to git branches that are not included in the allow-list, will be able to access the Cache Volumes, but their changes to the caches’ content will not be persisted in the end. You may also use an asterisk as a placeholder to match a branch name pattern.

Manage cache access per job

Instead of protecting your cache per branch, you can also select which jobs may write to the cache. This lets you share a cache amongst multiple jobs while some are not allowed to update its contents. Any job without commit rights can still access the cache and can also change contents locally. But any edits that it makes to the cache will be ignored for future runs.

Next steps

For advanced configuration see Runner Labels.
Last modified on September 22, 2026