apps/docs/content/docs/crafting-your-repository/caching.mdx
import { ExperimentalBadge } from "@/components/geistdocs/experimental-badge";
Turborepo uses caching to speed up builds, ensuring you never do the same work twice. When your task is cacheable, Turborepo will restore the results of your task from cache using a fingerprint from the first time the task ran.
Turborepo's caching results in significant time savings when working locally - and is even more powerful when Remote Caching is enabled, sharing a cache among your entire team and CI.
On this page, you'll learn:
You can try out Turborepo's caching behavior in three steps:
<Steps> <Step> ### Create a new Turborepo projectUse npx create-turbo@latest and follow the prompts to create a new Turborepo.
npx create-turbo@latest
If you have turbo installed globally, run turbo build in your repository.
Alternatively, you can run the build script in package.json using your package manager.
npm run build
bun run build
This will result in a cache miss, since you've never ran turbo before with this set of inputs in this repository. The inputs are turned into a hash to check for in your local filesystem cache or in the Remote Cache.
Run turbo build again. You will see a message like this:
Because the inputs' fingerprint is already in the cache, there's no reason to rebuild your applications from zero again. You can restore the results of the previous build from cache, saving resources and time.
Turborepo stores the results of tasks in the .turbo/cache directory on your machine. However, you can make your entire organization even faster by sharing this cache with your teammates and CI.
To learn more about Remote Caching and its benefits, visit the Remote Caching page.
First, authenticate with your Remote Cache provider:
npx turbo login
Then, link the repository on your machine to Remote Cache:
npx turbo link
Now, when you run a task, Turborepo will automatically send the outputs of the task to Remote Cache. If you run the same task on a different machine that is also authenticated to your Remote Cache, it will hit cache the first time it runs the task.
For information on how to connect your CI machines to Remote Cache, visit the Constructing CI guide.
<Callout type="info"> By default, Turborepo uses [Vercel Remote Cache](https://vercel.com/docs/monorepos/remote-caching) with zero configuration. If you'd like to use a different Remote Cache, visit the [Remote Caching API documentation](/docs/core-concepts/remote-caching#self-hosting) </Callout>When working with Git worktrees, Turborepo automatically shares the local filesystem cache between the main worktree and any linked worktrees. This enables:
Git worktrees allow you to have multiple working directories attached to the same repository, each checked out to a different branch. When you create a linked worktree with git worktree add, Turborepo detects this configuration and automatically redirects the cache to the main worktree's .turbo/cache directory.
# Create a linked worktree for a feature branch
git worktree add ../my-feature feature-branch
# Run turbo in the linked worktree - cache is shared with main worktree
cd ../my-feature
turbo build
When worktree cache sharing is active, you'll see a message in the output:
• Remote caching enabled, using shared worktree cache
Git worktree cache sharing works alongside Remote Caching. When both are enabled:
This means a task built in one worktree can be restored from the shared local cache in another worktree instantly, without a network request. If the local cache doesn't have the artifact, Turborepo will fall back to the Remote Cache as usual.
Turborepo caches two types of outputs: Task outputs and Logs.
Turborepo caches the file outputs of a task that are defined in the outputs key of turbo.json. When there's a cache hit, Turborepo will restore the files from the cache.
The outputs key is optional, see the API reference for how Turborepo behaves in this case.
If you're running into errors with files not being available when you hit cache, make sure that you have defined the outputs for your task.
</Callout>Turborepo always captures the terminal outputs of your tasks, restoring those logs to your terminal from the first time that the task ran.
You can configure the verbosity of the replayed logs using the --output-logs flag or outputLogs configuration option.
Inputs are hashed by Turborepo, creating a "fingerprint" for the task run. When "fingerprints" match, running the task will hit the cache.
Under the hood, Turborepo creates two hashes: a global hash and a task hash. If either of the hashes change, the task will miss cache.
| Input | Example |
|---|---|
Resolved task definition from root turbo.json and package turbo.json | Changing outputs in either root turbo.json or Package Configuration |
| Lockfile changes that affect the Workspace root | Updating dependencies in root package.json will cause all tasks to miss cache |
globalDependencies file contents | Changing ./.env when it is listed in globalDependencies will cause all tasks to miss cache |
Values of variables listed in globalEnv | Changing the value of GITHUB_TOKEN when it is listed in globalEnv |
| Flag values that affect task runtime | Using behavior-changing flags like --cache-dir, --framework-inference, or --env-mode |
| Arbitrary passthrough arguments | turbo build -- --arg=value will cause all tasks to miss cache when compared to either turbo build or turbo build -- --arg=diff (including dependencies of build that did not receive --arg=value) |
| Input | Example |
|---|---|
| Package Configuration changes | Changing a package's turbo.json |
| Lockfile changes that affect the package | Updating dependencies in a package's package.json |
Package's package.json changes | Updating the name field in a package's package.json |
| File changes | Defaults to all source-controlled files in the package directory. Configurable with inputs |
Turborepo has a --dry flag that can be used to see what would happen if you ran a task without actually running it. This can be useful for debugging caching issues when you're not sure which tasks you're running.
For more details, visit the --dry API reference.
Turborepo has a --summarize flag that can be used to get an overview of all of a task's inputs, outputs, and more. Comparing two summaries will show why two task's hashes are different. This can be useful for:
turborepo-summary - Generate human-readable reports from Turborepo run summary JSON outputturborepo-summary-action - GitHub Action wrapping turborepo-summary to append them to GitHub Actions Job SummarySometimes, you may not want to write the output of tasks to the cache. This can be set permanently for a task using "cache": false or for a whole run using the --cache <options> flag.
If you want to force turbo to re-execute a task that has been cached, use the --force flag. Note that this disables reading the cache, not writing.
It's possible to create scenarios where caching ends up being slower than not caching. These cases are rare, but a few examples include:
While these situations are rare, be sure to test the behavior of your projects to determine if disabling caching in specific places provides a performance benefit.
Now that you've seen how Turborepo's caching makes your repository faster, let's take a look at how to develop applications and libraries in your Turborepo.