skip to content

How does configuration on demand compare to the configuration cache, and which should a modern build prefer?

level: seniorimportance: must knowfreq 34%

answer

  1. config-on-demand trims; config cache eliminates the phase
  2. config cache = serialized task graph, keyed by tasks+inputs
  3. .gradle/configuration-cache
  4. config cache also unlocks parallelism + is the recommended path
  5. both need self-contained projects

basics

~20 s

Configuration on demand only reduces how many projects are configured this run. The configuration cache caches the whole configured task graph and reuses it across runs, skipping the configuration phase entirely. Modern builds should prefer the configuration cache.

solid answer

~50 s

Both attack the cost of the **configuration phase**, but differently. **Configuration on demand** still runs configuration every build — it just configures fewer projects (only those reachable from the requested tasks). **Configuration cache** serializes the *result* of the entire configuration phase to disk keyed by the requested tasks and inputs (build scripts, properties, env), then on a cache hit it **skips configuration altogether** and goes straight to execution, also enabling more parallelism. The configuration cache is strictly more powerful and is the direction Gradle is investing in. It also imposes stricter requirements: tasks must not read mutable state at execution time, must declare inputs properly, and cross-project access at execution time is forbidden — the same self-containment that makes configure-on-demand safe. For new or actively maintained builds, the recommendation is to make the build configuration-cache-compatible and rely on it; configure-on-demand is older and largely subsumed.

code

properties · 5 lines
properties
# gradle.properties — modern recommendation
org.gradle.configuration-cache=true
org.gradle.parallel=true
org.gradle.caching=true
# org.gradle.configureondemand=true  # legacy; usually unnecessary once config cache is on

go deeper

for a junior

Know that the configuration cache reuses configuration across builds while configure-on-demand only configures fewer projects each build.

for a middle

Explain that the configuration cache skips the whole phase on a hit and is keyed by tasks + inputs.

for a senior

Compare them across persistence, parallelism, and maturity, and recommend the configuration cache for modern builds.

for a principal

Drive a migration strategy: harden the build for configuration-cache compatibility (self-contained projects, lazy providers) and retire reliance on configure-on-demand across the org.

## Same enemy, different weapons The configuration phase re-runs build logic on every invocation. Two features reduce that cost: | Aspect | Configuration on demand | Configuration cache | |---|---|---| | What it skips | Configuration of **irrelevant projects** | The **entire configuration phase** on a cache hit | | Runs configuration each build? | Yes (a smaller subset) | No — reuses the serialized task graph | | Benefit on repeated identical builds | Same trimmed cost each time | Near-zero configuration cost after first run | | Enables extra parallelism | No (separate from `--parallel`) | Yes — tasks across projects run in parallel by default on a cache hit | | Maturity / direction | Older, incubating, de-emphasized | Actively developed, recommended path | ## How the configuration cache works On the first run, Gradle configures the build and **serializes** the resulting task graph (and the state tasks need) to a cache entry under `.gradle/configuration-cache`, keyed by the **requested task names plus relevant inputs** (build script contents, `gradle.properties`, environment variables and system properties that were read, etc.). On a subsequent run with the same key, Gradle **deserializes** the graph and jumps straight to execution — no script evaluation, no project configuration. ```bash gradle :app:assemble --configuration-cache # or persistently: # org.gradle.configuration-cache=true ``` ## Why it supersedes configure-on-demand Configure-on-demand only ever *narrows* a phase that still runs. The configuration cache can *eliminate* that phase on a hit — a larger win, and one that scales better as a build grows. Both rely on the same discipline (self-contained per-project configuration, no execution-time cross-project mutation), so a build hardened for the configuration cache is also well-behaved under configure-on-demand. ## Requirements / constraints of the configuration cache - Tasks must **not read live project state at execution time** — capture inputs at configuration time into `Provider`/`Property` or `@Input`/serializable fields. - No `project` access from task actions; use injected services and lazy providers instead. - Inputs from the environment must be read through Gradle's value-source/provider APIs so changes invalidate the cache key. ## Can you use both? They're not mutually exclusive, but combining them is rarely worth it: once the configuration cache is in play and hitting, configure-on-demand has little left to save (the phase it trims is being skipped wholesale). Practical advice: target configuration-cache compatibility; treat configure-on-demand as a legacy stopgap for builds not yet migrated.

  • What invalidates a configuration-cache entry?
    Any change to the cache key inputs: requested task names, build script contents, gradle.properties, or environment variables/system properties that the build reads. A change forces a full reconfigure and re-serialization.
  • Why does the configuration cache, but not configure-on-demand, let cross-project tasks run in parallel by default?
    Because the configuration cache requires tasks to declare inputs/outputs and avoid execution-time cross-project state, Gradle can prove independence and schedule tasks across projects in parallel safely; configure-on-demand makes no such guarantees.
  • Is configure-on-demand still useful if your build can't yet support the configuration cache?
    Possibly — if you frequently build narrow task subsets in a large multi-project build, it can still trim configuration time as an interim measure while you migrate.

Configure-on-demand is cooking fewer dishes each night; the configuration cache is meal-prepping once and reheating — you skip the cooking entirely on later nights.

saying these in an interview costs you the question

  • Saying configure-on-demand caches results across builds — it does not; it reconfigures (a subset) every time.
  • Claiming the two are interchangeable; the configuration cache is strictly more capable.
  • Confusing the configuration cache with the build (output) cache — they cache different things (task graph vs task outputs).

context