Caching

Purpose and Scope

Caching is the mechanism Turborepo uses to avoid repeating work in JavaScript and TypeScript workspaces. A cacheable task produces results from a known set of inputs, and Turborepo records a fingerprint for those inputs the first time the task succeeds. Later, when the same task is requested with the same fingerprint, Turborepo can restore the previous results rather than starting from zero. The user-facing promise in the first-party guide is simple: never do the same work twice when the task is deterministic and its relevant inputs and outputs are described accurately.

Sources: apps/docs/content/docs/crafting-your-repository/caching.mdx

This page focuses on local caching first: where artifacts are stored, how cache misses become cache hits, why configured outputs matter, and what makes a task safe to cache. It also explains how local behavior extends to remote and CI scenarios, because local cache correctness is the foundation for shared cache correctness. Remote Caching can multiply the value of a good setup across teammates and build machines, but it also shares the consequences of incomplete inputs, missing outputs, or unsafe console output. Treat the local cache as the place to prove the task contract before scaling it.

Sources: apps/docs/content/docs/crafting-your-repository/caching.mdx, apps/docs/content/docs/core-concepts/remote-caching.mdx

Relevant Source Files

  • apps/docs/content/docs/crafting-your-repository/caching.mdx — Primary guide for Turborepo task caching, first cache hit workflow, local cache directory, determinism warning, remote-cache entry points, and troubleshooting scope.
  • apps/docs/content/docs/core-concepts/remote-caching.mdx — Conceptual explanation of why local-only caches duplicate work across machines and how a shared remote cache prevents that.
  • apps/docs/content/blog/free-vercel-remote-cache.mdx — Announcement-style source for Vercel Remote Cache availability, local linking commands, Vercel automatic configuration, and external CI environment variables.
  • apps/docs/content/docs/crafting-your-repository/configuring-tasks.mdx — Task-configuration guide that explains tasks, package scripts, dependencies, parallelization, and the need to specify outputs for caching.
  • apps/docs/content/docs/crafting-your-repository/constructing-ci.mdx — CI guide covering remote cache environment variables, running the same tasks in CI, and the relationship between task setup and pipeline speed.
  • apps/docs/content/docs/crafting-your-repository/creating-an-internal-package.mdx — Internal-package guide showing how package relationships and package build scripts affect the package graph and cached build workflows.

Core Caching Model

A Turborepo task is a script that the tool discovers by matching a task name from the root configuration with scripts in package manifests. When you run a task such as a build across the repository, Turborepo can parallelize independent work and order dependent work through the package and task graphs. Caching sits on top of that orchestration. The scheduler decides which tasks are needed, then the cache lookup decides whether each task must execute or whether its prior outputs and logs can be restored from an existing artifact.

Sources: apps/docs/content/docs/crafting-your-repository/configuring-tasks.mdx, apps/docs/content/docs/crafting-your-repository/caching.mdx

The cache key is described in the docs as a hash or fingerprint of the task inputs Turborepo knows about. On a first run in a new repository, that fingerprint is not present, so the task is a cache miss and Turborepo executes it. On a later run with the same known inputs, the fingerprint can be found and the task becomes a cache hit. This is why cache behavior is not only about speed. It is a correctness contract between task configuration, workspace structure, environment handling, and the files a task reads or writes.

Sources: apps/docs/content/docs/crafting-your-repository/caching.mdx

Turborepo assumes cacheable tasks are deterministic. Deterministic means the task should produce the same outputs when Turborepo sees the same inputs. If a build reads an untracked file, depends on an environment value that is not modeled, or writes output outside the configured output locations, the cache may look valid while restoring stale or incomplete work. The docs call this out explicitly because cache hits are only trustworthy when the task’s observable behavior is captured by the inputs Turborepo fingerprints and the outputs it restores.

Sources: apps/docs/content/docs/crafting-your-repository/caching.mdx

First Local Cache Hit Flow

The fastest way to observe the model is to create a new project, run a build once, and then run it again. The caching guide recommends starting with a new Turborepo project created through the standard scaffold command. After the first build, Turborepo has seen that set of inputs and can store the results in the local filesystem cache. The second build demonstrates the important behavioral difference: when the fingerprint is already available, there is no reason to rebuild every package from scratch, so Turborepo restores the previous results.

Sources: apps/docs/content/docs/crafting-your-repository/caching.mdx

npx create-turbo@latest
turbo build
turbo build

If the turbo binary is not installed globally, the same task can be reached through the repository’s package manager script. The guide shows package-manager variants for running the build script, and the underlying idea is the same: the root script eventually invokes Turborepo, Turborepo evaluates the task graph, and each cacheable task either executes or restores. The first run is expected to miss because the repository has no matching cache record yet. A later run can show the full value of cache reuse when inputs have not changed.

Sources: apps/docs/content/docs/crafting-your-repository/caching.mdx

Outputs and Task Configuration

Caching file artifacts requires task configuration, not only task names. The task configuration guide warns that defining a build task with no outputs lets Turborepo run matching package scripts, but it will not cache file outputs in the way most build workflows expect. Outputs tell Turborepo which files or directories are the product of a task and should be restored later. For compiled packages, that often aligns with the package’s build script and generated distribution directory, such as TypeScript compiling source files into build artifacts consumed by applications or other packages.

Sources: apps/docs/content/docs/crafting-your-repository/configuring-tasks.mdx, apps/docs/content/docs/crafting-your-repository/creating-an-internal-package.mdx

Task dependencies affect when cached work is considered and restored. A common build task uses dependency ordering so libraries build before applications that consume them. In Turborepo configuration, the guide introduces dependency relationships such as running the same task in package dependencies before the target package. That ordering matters even with caching, because the task graph still represents the correct workflow. A dependency task may be restored from cache, while a dependent task may execute, or the reverse may happen depending on which fingerprints match the current inputs.

Sources: apps/docs/content/docs/crafting-your-repository/configuring-tasks.mdx, apps/docs/content/docs/crafting-your-repository/creating-an-internal-package.mdx

{
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"]
    }
  }
}

Local Cache Directory and Remote Extension

By default, Turborepo stores task results in the local filesystem, with the caching guide naming the repository-local cache directory as the place where results are kept on your machine. This local cache speeds up repeated work for one developer on one checkout. The limitation is scope: another teammate, CI worker, platform build, or separate machine cannot benefit from your local-only artifact. The remote caching concept page frames this as duplicated work, because identical task inputs still have to be re-executed on every machine unless the cache is shared.

Sources: apps/docs/content/docs/crafting-your-repository/caching.mdx, apps/docs/content/docs/core-concepts/remote-caching.mdx

Remote Caching adds a shared cache server that stores the results of tasks for the team and CI. The local workflow begins by authenticating and linking the repository, after which Turborepo can automatically send task outputs to the remote cache and restore matching artifacts from it. Vercel Remote Cache is documented as free to use, including for repositories not hosted on Vercel, and the announcement notes that Vercel builds are automatically configured while other CI providers authenticate with environment variables. The local commands remain intentionally small.

Sources: apps/docs/content/docs/core-concepts/remote-caching.mdx, apps/docs/content/blog/free-vercel-remote-cache.mdx

npx turbo login
npx turbo link

CI, Environment, and Safety Considerations

CI should run the same registered tasks that developers run locally, but with remote cache credentials available to the pipeline. The CI guide names the two key variables for Vercel Remote Cache style authentication: one bearer token and one account or team identifier. Once those values are configured, task invocations can hit the shared cache and shorten build, lint, test, and other workflow stages. Vercel’s built-in CI/CD is described as automatically connected to the managed remote cache, while external CI vendors need explicit environment configuration.

Sources: apps/docs/content/docs/crafting-your-repository/constructing-ci.mdx, apps/docs/content/blog/free-vercel-remote-cache.mdx

TURBO_TOKEN=...
TURBO_TEAM=...
turbo run build test lint

Remote cache safety starts with the same deterministic-task rule as local caching, but it has a broader blast radius. The remote caching guide cautions that logs are treated as artifacts, so teams should be aware of what tasks print to the console. It also points readers back to environment-variable handling before relying heavily on shared artifacts. Practically, this means a cache miss is not always bad; it may be the correct result when inputs changed. A suspicious cache hit is more important to investigate, especially after changing environment usage, generated files, or output directories.

Sources: apps/docs/content/docs/core-concepts/remote-caching.mdx, apps/docs/content/docs/crafting-your-repository/caching.mdx

Compact Reference

ConcernConcrete entry pointsBehavior
First local cacheturbo build, package-manager build scriptsFirst run misses, later identical input fingerprints can restore results.
Local cache storage.turbo/cacheStores task results on the current machine by default.
Remote cache setupnpx turbo login, npx turbo linkAuthenticates and links a repository so artifacts can be shared.
CI remote cache authTURBO_TOKEN, TURBO_TEAMLets external CI providers access the Remote Cache.
Task discoverytasks entries matched to package scriptsTurborepo runs scripts with the same task name across packages.
Task orderingdependsOn, including dependency-first build patternsEnsures package dependencies complete before dependents when configured.
File restorationoutputsDeclares the artifacts Turborepo should cache and restore.
Forced execution--force, TURBO_FORCE, task cache configurationBypasses or changes normal cache reuse for a run or task.

Next Steps

Use this page as a checklist when a cache does not behave as expected. First, confirm the task is declared in the root task configuration and that package scripts exist with the matching name. Next, verify that outputs describe the files the task actually produces and that the task is deterministic for the inputs Turborepo knows about. After local cache hits are trustworthy, enable Remote Caching and wire the CI variables so the same artifacts can be shared safely across machines. For deeper follow-up, read the Remote Caching, Configuring Tasks, Environment Variables, and Constructing CI pages.