skip to content

Configuration On Demand

Configuring only the projects the requested tasks actually need, and why the configuration cache largely supersedes it. Interviewers ask because it is a tempting flag that carries real correctness caveats.

on this pageshow

questions

5

What is Gradle's configuration-on-demand feature, and what problem does it solve in large multi-project builds?

level: middleimportance: must knowfreq 38%

answer

  1. configures only relevant projects
  2. root + task owners + project deps
  3. org.gradle.configureondemand / --configure-on-demand
  4. breaks with cross-project config
  5. superseded by configuration cache

basics

~10 s

Configuration on demand tells Gradle to configure only the projects needed for the requested tasks, instead of configuring every project in the build. It speeds up the configuration phase in large multi-project builds.

solid answer

~40 s

Every Gradle build has a **configuration phase** that runs each project's build script to build the task graph, followed by an **execution phase**. By default Gradle configures *all* projects, even ones irrelevant to the requested task — costly in builds with hundreds of subprojects. **Configuration on demand** (`--configure-on-demand` flag, or `org.gradle.configureondemand=true` in `gradle.properties`) makes Gradle configure only the root project plus the projects required to run the requested tasks, walking project dependencies to pull in transitively-needed projects. For a build with 200 modules where you only need one app and its dependencies, this can dramatically cut configuration time. It's an older optimization that predates the configuration cache; for new builds the configuration cache generally supersedes it and is the recommended path.

code

properties · 5 lines
properties
# gradle.properties
org.gradle.configureondemand=true

# or per-invocation:
# gradle :app:assemble --configure-on-demand

go deeper

for a junior

Know it configures only the projects needed for the requested tasks instead of all of them, enabled via a flag or gradle.properties.

for a middle

Explain the configuration vs execution phases, exactly which projects get configured (root + task owners + project deps), and how to enable it.

for a senior

Discuss its limitations with cross-project configuration and why the configuration cache supersedes it for modern builds.

for a principal

Frame it within an org's build-performance strategy: when to lean on it vs investing in configuration-cache compatibility across a large monorepo.

## The two phases of a Gradle build Every Gradle invocation runs in distinct phases: 1. **Initialization** — `settings.gradle(.kts)` runs; Gradle decides which projects participate. 2. **Configuration** — every participating project's build script is *executed* to register and wire up tasks, building the full task graph (the DAG). This runs even for projects you didn't ask to build. 3. **Execution** — the requested tasks (and their dependencies) actually run. In a build with many subprojects, the configuration phase is pure overhead for projects you never touch. If `:app` depends only on `:core`, configuring the other 198 modules is wasted work on every invocation. ## What configuration on demand does With configuration on demand enabled, Gradle configures **only the projects relevant to the requested tasks**: - The **root** project (always configured). - The projects that **own** the requested tasks. - Projects reachable through **project dependencies** (e.g. an `implementation(project(":core"))` dependency pulls `:core` in). Gradle discovers the needed set by evaluating projects lazily as task references and project dependencies are resolved, rather than eagerly evaluating all of them up front. ## How to enable it Two ways: ```properties # gradle.properties (persistent, per-project or per-user) org.gradle.configureondemand=true ``` ```bash # one-off, per invocation gradle :app:assemble --configure-on-demand ``` ## Caveats and limitations - It's a **heuristic**: builds with **cross-project configuration** (e.g. `allprojects { }`, `subprojects { }`, or one project reaching into another via `project(":other").tasks…`) can behave incorrectly, because the project that *would* configure another may never be configured. Gradle warns these builds are not well-supported under configure-on-demand. - It only helps when you run **a subset** of the build. A full `build` that touches everything sees little benefit. - It is **incubating/legacy** relative to the **configuration cache**, which caches the *result* of the entire configuration phase and reuses it across invocations — a strictly more powerful optimization. Modern guidance is to invest in making the build configuration-cache-compatible rather than relying on configure-on-demand. ## Mental model Configure-on-demand reduces *how much* of the configuration phase runs this time; the configuration cache reduces *whether the configuration phase runs at all* (by reusing a cached task graph). They target the same cost from different angles.

  • Which projects get configured when you run `:app:assemble` with configure-on-demand on, and `:app` depends on `:core`?
    The root project, `:app` (it owns the task), and `:core` (pulled in as a project dependency). Other unrelated subprojects are skipped.
  • Why does a full `./gradlew build` see little benefit from configure-on-demand?
    Because `build` typically touches every subproject, so the set of 'relevant' projects is essentially all of them — there's nothing to skip.

Like a buffet versus à la carte: by default Gradle cooks every dish (configures every project) whether or not you order it; configure-on-demand only cooks the dishes you actually ordered plus their required side ingredients.

saying these in an interview costs you the question

  • Claiming it speeds up the execution phase — it only trims the configuration phase.
  • Saying it configures only the single requested project (it also pulls in project dependencies and the root).
  • Confusing it with the build cache (which caches task *outputs*, not configuration).

context

open as a page

With configuration on demand enabled, how does Gradle decide which projects to configure for a given set of requested tasks?

level: middleimportance: must knowfreq 30%

basics

~10 s

Gradle always configures the root project, plus the projects that own the requested tasks, plus any projects reachable through project dependencies. Unrelated subprojects are skipped.

open as a page

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

level: seniorimportance: must knowfreq 34%

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.

open as a page

How do you enable configuration on demand, and what's the difference between the command-line flag and the gradle.properties setting?

level: juniorimportance: should knowfreq 25%

basics

~10 s

Use --configure-on-demand on the command line for a single build, or set org.gradle.configureondemand=true in gradle.properties to make it the default for every build of that project.

open as a page

A team enabled configuration on demand and now some tasks intermittently fail or aren't found. What's the likely cause and how would you diagnose it?

level: seniorimportance: should knowfreq 22%

basics

~20 s

The build probably relies on cross-project configuration (allprojects/subprojects blocks or one project reaching into another). Under configure-on-demand the project that applies that wiring may never be configured, so tasks it would create or modify go missing.

open as a page