skip to content

What does org.gradle.configuration-cache do, and how does it differ from the build cache?

level: seniorimportance: must knowfreq 60%

answer

  1. caches the configuration phase / task graph
  2. build cache = outputs; config cache = graph
  3. no live Project access at execution
  4. capture state via Provider / ValueSource
  5. --configuration-cache, problems=warn

basics

~10 s

org.gradle.configuration-cache=true caches the result of the configuration phase (the task graph) so subsequent builds skip re-configuring and run tasks straight away. The build cache, by contrast, caches task execution outputs.

solid answer

~50 s

The **configuration cache** (`org.gradle.configuration-cache=true`) serializes the result of the **configuration phase** — the fully built task graph and the state needed to run it — so that on a subsequent invocation with the same inputs Gradle skips configuration entirely and goes straight to execution. This is different from the **build cache**, which caches **task outputs** from the execution phase. The configuration cache also enables parallel configuration of projects and aggressively isolates tasks, which is why it enforces strict rules: tasks must not read live `Project` state at execution time, must not use forbidden APIs (e.g. `Task.project` during execution), and must capture external state through `Provider`/`ValueSource`. Enable persistently with the property, or per build with `--configuration-cache`; problems are reported and a cache entry is reused only when inputs (build scripts, env/system properties read, input files) are unchanged.

code

properties · 2 lines
properties
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=warn

go deeper

for a junior

Recognize it caches the configuration phase to skip re-configuring on later runs.

for a middle

Contrast it with the build cache (graph vs outputs) and know how to enable it.

for a senior

Explain the execution-time restrictions, ValueSource/Provider capture, invalidation inputs, and the problems=warn migration path.

for a principal

Drive adoption across a monorepo: enforce compatibility in CI, track the problems report to zero, and combine with parallel + build cache for full speedups.

## The two phases of a Gradle build Every build has a **configuration phase** (evaluate settings + all build scripts, register and wire tasks, build the task graph) and an **execution phase** (run the selected tasks). On large builds, configuration alone can take many seconds on *every* invocation. ## What the configuration cache stores `org.gradle.configuration-cache=true` serializes the **outcome of configuration**: the task graph and the state each task needs to execute. On the next run, if the cache inputs are unchanged, Gradle **skips the configuration phase entirely** and deserializes the graph, jumping straight to execution. It also runs configuration of independent projects in parallel and caches across invocations. ## Cache invalidation inputs The entry is keyed on things the build *read* during configuration: the set of requested tasks, build script contents, system properties / environment variables consumed, and declared input files. Reading an undeclared environment variable or file at configuration time is a problem the cache must track, which is why Gradle restricts how external state is accessed. ## Why it imposes rules (and how it differs from build cache) | | Configuration cache | Build cache | |---|---|---| | Caches | the task graph / configuration result | task **outputs** (execution) | | Phase | configuration | execution | | Key | requested tasks + scripts + read inputs | per-task input hash | | Enable | org.gradle.configuration-cache | org.gradle.caching | Because tasks are deserialized without re-running configuration, a task may **not** reach back into live `Project`/`Gradle` objects at execution time. Forbidden patterns include calling `task.project` in a task action, referencing other tasks directly, or reading mutable build state. The fix is to capture everything a task needs as **inputs** up front — typically via `Property`/`Provider` wiring and `ValueSource` for external state (files, env, command output). ```kotlin // Capture external state cleanly for the configuration cache abstract class GitShaValueSource : ValueSource<String, ValueSourceParameters.None> { override fun obtain(): String = ProcessBuilder("git", "rev-parse", "HEAD").start() .inputStream.bufferedReader().readText().trim() } val gitSha = providers.of(GitShaValueSource::class) {} tasks.register("printSha") { val sha = gitSha // captured as input, CC-safe doLast { println(sha.get()) } } ``` ## Enabling and diagnosing - Persistent: `org.gradle.configuration-cache=true`. - Per build: `--configuration-cache` (and `--no-configuration-cache`). - Strictness: `org.gradle.configuration-cache.problems=warn` downgrades problems to warnings during migration; Gradle writes an HTML report listing incompatibilities. ## Relationship to other flags It composes with `org.gradle.parallel` and `org.gradle.caching` — together they cut both configuration and execution time. Configuration cache effectively *requires* the decoupling that parallel execution also wants, so adopting it tends to harden a build for both.

  • Why can't a configuration-cache-compatible task call task.project in its doLast action?
    At execution the task is deserialized from the cache without a live Project graph. Reaching into Project state would bypass the cache's input tracking and break reproducibility, so it is forbidden; needed values must be captured as inputs beforehand.
  • How do you read an environment variable or git SHA at configuration time without breaking the cache?
    Through providers.environmentVariable(...) or a ValueSource (providers.of(...)). These register the read as a tracked cache input so the entry invalidates correctly when it changes, rather than reading it ad hoc.
  • What invalidates a configuration cache entry?
    Changes to requested tasks, build/settings script contents, or any read inputs (system properties, environment variables, input files) the build consumed during configuration.

saying these in an interview costs you the question

  • Saying it caches task outputs — that is the build cache.
  • Believing tasks can freely access Project state at execution under the configuration cache.
  • Thinking configuration cache and build cache are the same flag.

context