Turborepo Cache Misses in CI - Restore Remote Cache Hits
Turborepo hashes task inputs and replays cached outputs on a match. When CI never hits the cache - no "FULL TURBO" - the cause is a missing remote cache, non-deterministic inputs, or outputs that were never declared so nothing was stored.
What this error means
CI rebuilds every task on every run and never prints ">>> FULL TURBO". A fresh runner has no local cache and, without a remote cache, cannot reuse a previous run’s work. Locally it hits because .turbo persists.
Tasks: 6 successful, 6 total
Cached: 0 cached, 6 total # expected some cached
Time: 2m14s
# desired: >>> FULL TURBOCommon causes
No remote cache configured
The cache lives in .turbo on one machine. Without Remote Caching (Vercel or a self-hosted cache) or a restored .turbo directory, each CI runner starts cold.
Inputs vary between runs
Env vars not listed in globalEnv/task env, timestamps, or untracked files change the hash, so turbo always misses.
Outputs not declared
If a task’s outputs are not declared in turbo.json, turbo has nothing to cache and replay, so subsequent runs cannot hit.
How to fix it
Enable remote caching in CI
Provide the team and token so runners share a remote cache.
export TURBO_TOKEN=${{ secrets.TURBO_TOKEN }}
export TURBO_TEAM=my-team
turbo run buildDeclare outputs and relevant env
List the files a task produces and any env vars that affect its result so hashing is correct and replayable.
{
"tasks": {
"build": {
"outputs": ["dist/**", ".next/**"],
"env": ["NODE_ENV"]
}
}
}Debug a miss with the dry run
turbo run build --dry=json | jq '.tasks[] | {task, hash, cache}'How to prevent it
- Configure remote caching so CI runners share build outputs.
- Declare
outputsandenvfor every cacheable task. - Keep inputs deterministic and list env vars that affect results.