What is the task execution graph in Gradle, and at what point in the build lifecycle is it constructed?
answer
- three phases: init, config, execution
- DAG built between configuration and execution
- nodes=tasks, edges=dependencies
- acyclic or build fails
- requested tasks walked transitively
basics
~10 sIt's a directed acyclic graph (DAG) of the tasks Gradle will run for the requested build, ordered by their dependencies. Gradle builds it after the configuration phase finishes and before execution starts.
solid answer
~40 sGradle runs in three phases: initialization, configuration, then execution. The task execution graph (a DAG) is computed at the boundary between configuration and execution. During configuration, every task is created and its relationships (`dependsOn`, `finalizedBy`, declared input/output wiring) are registered. Once configuration finishes, Gradle takes the tasks you requested on the command line and walks their dependencies transitively to build a complete, ordered, deduplicated graph. It's *acyclic* — a cycle between task dependencies is a build error. Only after the full graph exists does execution begin, running each task once in an order that respects all edges. This 'plan everything, then run' model is why the graph is available before any task action executes.
code
kotlin · 6 linestasks.register("compile") { doLast { println("compiling") } }
tasks.register("test") {
dependsOn("compile")
doLast { println("testing") }
}
// gradle test -> graph: compile, test -> runs compile then testgo deeper
Name the three phases and state that the DAG is built after configuration, before execution.
Explain transitive walking of requested tasks and why the graph must be acyclic.
Connect plan-then-run to up-to-date checks, caching, and parallelism reasoning over the whole plan.
Discuss how the global graph view enables build-wide optimizations and how configuration cost trades against this planning model.
## The three lifecycle phases Every Gradle build moves through three phases in strict order: 1. **Initialization** — Gradle decides which projects participate (reads `settings.gradle(.kts)`) and creates the `Project` objects. 2. **Configuration** — Gradle evaluates every build script, *creating and configuring* tasks and registering their relationships. No task *actions* run yet. 3. **Execution** — Gradle runs the selected tasks' actions in dependency order. ## Where the graph fits The **task execution graph** is computed *between* configuration and execution. It is a **DAG (directed acyclic graph)**: nodes are tasks, edges are dependency relationships, and it must contain no cycles. During configuration, relationships are declared but not yet resolved into an ordering. Once configuration completes, Gradle: 1. Takes the **requested tasks** (what you typed, e.g. `gradle build`). 2. Walks their dependencies **transitively** — `dependsOn`, implicit dependencies inferred from declared inputs/outputs, and `mustRunAfter`/`shouldRunAfter` ordering hints. 3. Produces a single, deduplicated, topologically-sortable graph of every task that must run, plus any `finalizedBy` finalizers. ## Why acyclic matters If task A depends on B and B (transitively) depends on A, there is no valid execution order, so Gradle fails with a *circular dependency* error before any action runs. This guarantees a deterministic order. ## Plan-then-run Because the **whole** graph is built first, Gradle knows up front exactly what will run. This enables features like up-to-date checking, the build cache, and parallel execution to reason about the entire plan instead of discovering work as it goes. ```kotlin tasks.register("compile") { doLast { println("compiling") } } tasks.register("test") { dependsOn("compile") // edge: test -> compile doLast { println("testing") } } // `gradle test` builds a graph [compile, test] and runs compile, then test. ```
- Why must the graph be acyclic?A cycle means there is no valid topological order — Gradle can't decide which task to run first, so it fails fast with a circular dependency error instead of running anything.
- Can task actions run during configuration?No. Configuration only creates and wires tasks. Actions (`doFirst`/`doLast`/the task's work) run only during execution, after the graph exists.
Like a recipe: you read the whole recipe and lay out every step in order (the graph) before you start cooking — not improvising step-by-step.
saying these in an interview costs you the question
- Saying the graph is built during configuration of each script (it's built after all configuration completes).
- Claiming the graph can contain cycles or that order is non-deterministic.