quickstart →

Turborepo remote cache

Turborepo remote cache for GitHub Actions, served by Magic Cache from your own S3 bucket. One action input, no Vercel account, shared across branches.

Magic Cache serves Turborepo’s remote cache ↗ from the RunsOn agent on every runner. Task outputs are stored in the cache bucket of your stack: there is no cache server to run, and nothing leaves your AWS account.

Availability#

Since v3.6.0, on runners with Magic Cache (extras=s3-cache), with Flex and Fleet. The Overview covers how build tool caches are scoped and stored.

Enable it#

.github/workflows/ci.yml
jobs:
build:
runs-on: runs-on=${{ github.run_id }}/runner=8cpu-linux-x64/extras=s3-cache
steps:
- uses: runs-on/action@v2
with:
remote_cache: turbo
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- run: pnpm install --frozen-lockfile
- run: pnpm exec turbo run build test

The action points turbo at the agent with TURBO_API, and sets TURBO_TOKEN and TURBO_TEAM to runs-on: turbo needs both to turn its remote cache on, and the agent ignores them. turbo then prints Remote caching enabled, and cache hit, replaying logs for each task it restores.

  • Branch scoping: a job writes task outputs to its own branch or pull request, and reads its own first, then its base and default branch’s. The default branch warms the cache for pull requests, which can never change its entries.
  • Per platform: turbo’s task hash leaves out the runner’s OS and architecture, so each platform has its own entries.
  • Pull requests from forks read the cache without uploading: the action sets TURBO_CACHE=local:rw,remote:r for them, unless the job sets TURBO_CACHE.
  • Container jobs reach the agent too.
  • Signed artifacts (remoteCache.signature and TURBO_REMOTE_CACHE_SIGNATURE_KEY) work unchanged.

On vercel/ai ↗ (turbo build for its packages and three Next.js examples, 87 tasks) on an 8 vCPU runner:

BuildDurationTasks restored
No cache94–97 snone
Same commit again, on a new runner2.3–2.6 sall 87
On a new runner, after a one-line change in @ai-sdk/openai73 s48
On a new runner, after a one-line change in @ai-sdk/provider-utils, which most packages use74 s2

A change rebuilds its package and every task that depends on it. Both changes rebuild the three Next.js examples, the slowest tasks, so they take about as long.

pnpm install takes another 47 s in both cases: cache the pnpm store too, for example with pnpm/action-setup and actions/setup-node’s cache: pnpm.

A hit restores only the files a task lists in outputs in turbo.json, so list every file later steps need, and leave out files that change on every build, such as .next/cache/**. A job that already sets TURBO_API, TURBO_TOKEN, TURBO_TEAM or TURBO_TEAMID, for example for Vercel’s remote cache, keeps it: the action warns and leaves turbo alone. Remove them to use the agent’s cache.