What people mean by "GitHub Actions cache"
In practice, teams use the phrase GitHub Actions cache for different mechanisms:
actions/cacherestores directories such as~/.npm,.pnpm-store,~/.gradle, or language package caches.actions/upload-artifactstores files from a specific workflow run for humans or downstream jobs.- Remote build cache stores per-task outputs keyed by content hashes and can be reused by CI and developer machines.
They are complementary. A lot of confusion comes from expecting one layer to replace the others. If your goal is faster monorepo builds, start with how remote build caching works, then decide where actions/cache and artifacts still add value.
The three cache layers in GitHub Actions CI
| Mechanism | Best at | Key model | Typical misuse |
|---|---|---|---|
actions/cache | Reducing dependency install time by restoring package-manager caches. | Manual keys and restore-keys, often lockfile-based. | Caching build output directories and expecting task-level correctness. |
actions/upload-artifact | Keeping run outputs for download, review, and cross-job handoff. | Named by workflow run, job, and artifact name. | Treating artifacts as a build cache and reusing stale binaries by name. |
| Remote build cache (Nx/Turbo/Bazel/Gradle) | Skipping task execution when input hashes match exactly. | Content hash of task inputs, tool version, and declared env inputs. | Assuming dependency restore cache is unnecessary once remote cache is enabled. |
When to use actions/cache, artifacts, and remote cache
Use actions/cache for dependency restore caches
Save package-manager and tool download caches that are expensive to fetch but safe to reuse broadly. Good examples: npm/pnpm/yarn package caches, pip wheel caches, Maven/Gradle dependency caches.
Use artifacts for run deliverables
Upload test reports, coverage output, release bundles, SBOMs, and debug logs. Artifacts are for human and deployment workflows, not for deciding whether a task should execute.
Use remote build cache for the build graph itself
This is the mechanism that skips expensive monorepo tasks safely. A proper task cache understands task inputs and outputs, so it can restore exactly what a task would have produced. If you run Nx or Turborepo in Actions, this is the layer that removes redundant compile/test/lint work.
The practical model for most teams is: dependency caches with actions/cache, task cache with remote caching, artifacts for reporting and release handoff.
How to combine them in one workflow
A healthy GitHub Actions setup for a monorepo usually follows this order:
- Restore dependency directories with
actions/cache. - Install dependencies.
- Run your build tool with remote cache enabled (Nx or Turborepo).
- Upload reports and deployables as artifacts.
The key point is layering: dependency cache makes install faster; remote cache makes tasks disappear when unchanged; artifacts keep the outputs you need outside the job. If you want a managed remote-cache option with this model, Cachely is one, and the exact setup steps are in the docs.
Practical workflow snippets
1) Dependency restore cache (actions/cache)
- name: Restore npm cache
uses: actions/cache@v6
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-This speeds up dependency download. It does not replace task-level build cache.
2) Artifact upload for reports or deployables
- name: Upload test report
uses: actions/upload-artifact@v7
with:
name: test-report-${{ github.run_id }}
path: coverage/
if-no-files-found: error3) Nx remote cache in GitHub Actions
- name: Run affected tasks with remote cache
env:
NX_SELF_HOSTED_REMOTE_CACHE_SERVER: https://remote.cachely.dev
NX_SELF_HOSTED_REMOTE_CACHE_ACCESS_TOKEN: ${{ secrets.NX_CACHE_TOKEN }}
run: npx nx affected -t lint,test,build4) Turborepo remote cache in GitHub Actions
- name: Turbo build with remote cache
env:
TURBO_API: https://remote.cachely.dev
TURBO_TOKEN: ${{ secrets.TURBO_CACHE_TOKEN }}
TURBO_TEAM: your-team-slug
run: npx turbo run build test lintWhich actions/cache version should you pin?
Most workflows in the wild still say uses: actions/cache@v4, and most tutorials still teach it. Two major versions have shipped since, and the reason to care is the runner requirement rather than the feature list - the cache inputs (path, key, restore-keys) have not changed:
- v4 - runs on Node 20. Still functional and the safest pin if you operate older self-hosted runners.
- v5 - moved to the Node 24 runtime and therefore requires runner version
2.327.1or newer. GitHub-hosted runners satisfy this automatically; self-hosted fleets must be updated first, and this is the upgrade that breaks people. - v6 - an internal migration to ESM on top of the v5 runtime baseline. No workflow-visible input changes.
The practical rule: pin the major (@v6) so you get patches without surprises, and if you run self-hosted runners, confirm the runner version before moving off v4. Pinning a full commit SHA is stricter still and worth it for security-sensitive repositories, at the cost of doing your own updates. The same Node-runtime cadence applies to actions/checkout, actions/setup-node, and actions/upload-artifact, so upgrade them as a set rather than one at a time.
None of this changes the ceiling. A newer actions/cache restores your dependency directory marginally faster; it still cannot skip a compile, test, or lint task, because it has no idea what those tasks read. If your pipeline is slow because it rebuilds unchanged code, the version you pin is not the variable that matters - the cache layer is.
Common mistakes and why they hurt
- Overly broad cache keys in actions/cache. Keys like
node-modules-mainrestore old dependency state across commits and branches, causing hard-to-reproduce behavior. - Stale dependency caches that never rotate. Missing lockfile hash components means cache content drifts from declared dependencies.
- Expecting actions/cache to replace remote task cache. Directory restoration cannot reason about the task graph, so builds still execute work that a task cache would skip.
- Using artifacts as cache storage. Artifacts are run-scoped deliverables, not deterministic task-replay storage.
- No read-only token split for untrusted CI. Pull-request and fork pipelines should not share write tokens with protected branches. Use read-only tokens for untrusted builds to reduce cache-poisoning risk.
For deeper context on safe remote-caching trust models, see security and compare.
Troubleshooting checklist
actions/cache miss rate is unexpectedly high
- Check that your key includes lockfiles and OS/arch where needed.
- Use restore-keys only for safe fallbacks, not broad cross-branch reuse of mutable directories.
- Verify paths actually exist at restore and save steps.
Dependency cache restores but installs are still slow
- Confirm you are caching package-manager cache directories, not just installed project directories.
- Validate the package manager config is reading that cache path on Actions runners.
Remote cache hit rate is low in CI
- Audit task inputs for unstable env vars, timestamps, or path differences.
- Ensure CI and local runs use matching tool versions and lockfile state.
- Measure misses by target to find the noisy input source before changing key scope.
Build looked "cached" but output is wrong
- Check whether an artifact was reused by name instead of rebuilding with task cache semantics.
- Recheck your declared task outputs and input hashing config in the build tool.
Remote cache vs GitHub cache: decision guide
If your pain is mostly dependency download time, actions/cache might be enough. If your pain is repeated compile/test/lint work in a monorepo, you need remote task caching. Most teams with non-trivial CI use both. Use artifacts to publish outputs and reports, not to drive cache-hit decisions.
For a broader remote-cache implementation guide, read /remote-cache. To diagnose disappointing remote hits, use the cache hit-rate guide. For implementation details and rollout steps, use /docs. For pricing and alternatives, see /pricing and /compare.
Related guides
- What is a remote cache?The pillar guide to content-hashed keys, local vs remote caching, and safety.
- Improve cache hit rateDiagnose over-keying, env drift, unstable outputs, and missing outputs.
- Monorepo build performanceWhy monorepo builds get slow and the four cache layers that fix it.
- CI savings calculatorEstimate the build minutes, engineer hours, and CI cost remote caching saves.