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#
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 testThe 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:rfor them, unless the job setsTURBO_CACHE. - Container jobs reach the agent too.
- Signed artifacts (
remoteCache.signatureandTURBO_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:
| Build | Duration | Tasks restored |
|---|---|---|
| No cache | 94–97 s | none |
| Same commit again, on a new runner | 2.3–2.6 s | all 87 |
On a new runner, after a one-line change in @ai-sdk/openai | 73 s | 48 |
On a new runner, after a one-line change in @ai-sdk/provider-utils, which most packages use | 74 s | 2 |
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.