Subchapter 9.8
references/caching/RULE.mdMarkdown4 KBView on GitHub
Turborepo’s core principle: never do the same work twice.
fingerprint(inputs) → stored outputsIf inputs haven’t changed, restore outputs from cache instead of re-running the task.
These affect ALL tasks in the repo:
package-lock.json / yarn.lock / pnpm-lock.yamlglobalDependencies (or global.env when using globalConfiguration)globalEnv (or global.env)turbo.json configuration{
"globalDependencies": [".env", "tsconfig.base.json"],
"globalEnv": ["CI", "NODE_ENV"]
}These affect specific tasks:
inputs)package.json contentsenv keydependsOn)global.inputs (when using futureFlags.globalConfiguration — see below){
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["src/**", "package.json", "tsconfig.json"],
"env": ["API_URL"]
}
}
}When futureFlags.globalConfiguration is enabled, global.inputs files are not part of the global hash. Instead, they are prepended to every task’s inputs and folded into the task hash. This is a fundamental change from globalDependencies.
With globalDependencies (default):
task cache key = hash(global hash, task hash)
↑ includes globalDependencies file hashesChanging a globalDependencies file invalidates every task, regardless of task-level inputs. There is no way for a task to opt out.
With global.inputs (futureFlags.globalConfiguration):
task cache key = hash(global hash, task hash)
↑ includes global.inputs file hashes (merged with task inputs)global.inputs files are merged into each task’s input globs. This means:
"inputs": ["$TURBO_DEFAULT$", "!$TURBO_ROOT$/tsconfig.json"]global.env, etc. — but not file hashes from global.inputs){
"futureFlags": { "globalConfiguration": true },
"global": {
"inputs": ["tsconfig.json", ".env"]
},
"tasks": {
"build": {
"outputs": ["dist/**"]
},
"lint": {
"inputs": ["$TURBO_DEFAULT$", "!$TURBO_ROOT$/tsconfig.json"]
}
}
}In this example, changing tsconfig.json invalidates build (it’s in the task’s inputs) but not lint (which explicitly excludes it). With globalDependencies, both would have been invalidated.
outputs{
"tasks": {
"build": {
"outputs": ["dist/**", ".next/**"]
}
}
}.turbo/cache/
├── <hash1>.tar.zst # compressed outputs
├── <hash2>.tar.zst
└── ...Add .turbo to .gitignore.
On cache hit, Turborepo:
FULL TURBO in output)# First run - executes build, caches result
turbo build
# → packages/ui: cache miss, executing...
# → packages/web: cache miss, executing...
# Second run - same inputs, restores from cache
turbo build
# → packages/ui: cache hit, replaying output
# → packages/web: cache hit, replaying output
# → FULL TURBOoutputs array means task runs but nothing is cachedoutputs key cache nothing (use "outputs": [] to be explicit)