skip to content

A teammate says they'll use --dry-run to confirm a build is fast and side-effect-free. Why is that the wrong tool, and what would you reach for instead?

level: middleimportance: should knowfreq 30%

answer

  1. dry-run = map, not stopwatch
  2. executes nothing -> can't measure execution
  3. configuration still runs -> misleading timing
  4. side effects live in skipped actions
  5. use --profile / tasks.stats to measure

basics

~20 s

--dry-run only previews the task graph; it still runs configuration and skips all execution, so it can't measure execution speed and won't reveal execution-time side effects. Use --profile (or task timing) to measure where time goes.

solid answer

~40 s

`--dry-run` builds and prints the task graph but **executes nothing**, so it tells you *what would run*, not *how long it takes* or *what side effects execution has*. Two specific failures: (1) it can't confirm speed because no task actions run — and configuration still runs, so a build that's slow *in configuration* will still feel slow under `--dry-run` while a build that's slow *in execution* will look instant; (2) it can't validate that execution is side-effect-free because the side effects live in the actions it skips. For "is it fast and where?" use `--profile` for an HTML phase/task breakdown, or `-Dorg.gradle.internal.tasks.stats` for an aggregated console summary by task type/outcome. To check side effects, you actually have to run the tasks (ideally in a sandbox) and observe outputs.

go deeper

for a junior

Recognize --dry-run only previews tasks and runs nothing, so it can't time execution.

for a middle

Explain why timing is misleading (config runs, execution skipped) and name --profile / tasks.stats as the right tools.

for a senior

Articulate the map-vs-stopwatch model and prescribe a layered measurement workflow.

for a principal

Set team guidance on which tool answers which question; prevent false-confidence anti-patterns in CI gates.

## The mismatch `--dry-run` answers exactly one question: **what is the ordered set of tasks for this goal?** It does this by running configuration and printing the graph with `SKIPPED` markers. It deliberately does **not** execute task actions. So two claims people wrongly attach to it both fail: ### "It proves the build is fast" - No task **action** runs, so execution time is unmeasured — a build with three slow tests will look instantaneous. - Configuration **does** run, so paradoxically a configuration-heavy build is *not* instant under `--dry-run`. That means the timing you observe is a misleading mix: it includes configuration but excludes execution. It's the wrong instrument for a speed claim either way. ### "It proves nothing side-effecting happens" - The side effects of a build (files written, services called, artifacts published) live inside task **actions** and `@TaskAction` methods — precisely what `--dry-run` skips. So an absence of side effects under `--dry-run` proves nothing about a real run. - (Eager configuration-time side effects *would* still fire, but those are a configuration smell, not what the teammate is checking.) ## The right tools | Goal | Tool | |---|---| | What tasks will run / ordering | `--dry-run` | | Where did time go, by phase and task | `--profile` (HTML report) | | Aggregate by task type + cache/up-to-date outcomes | `-Dorg.gradle.internal.tasks.stats` | | Validate real side effects | actually execute, observe outputs (sandbox/CI) | ## A concrete workflow ```bash # 1. See the shape ./gradlew publish --dry-run # 2. Measure where time actually goes ./gradlew build --profile # 3. Check caching/incrementality health across task types ./gradlew build -Dorg.gradle.internal.tasks.stats=true ``` The mental model: `--dry-run` is a *map*, not a *stopwatch*. Use the stopwatch tools for timing.

  • Could --dry-run ever appear slow, and why?
    Yes — because configuration still runs. A build with heavy per-project configuration or eager work will take real time under --dry-run even though no task executes.
  • How would you actually verify a task has no unexpected side effects?
    Run it for real in an isolated/sandbox environment and observe what it writes or calls — there's no substitute, since the side effects are in the actions --dry-run skips.

saying these in an interview costs you the question

  • Asserting --dry-run measures execution time (it skips execution entirely).
  • Believing a clean --dry-run guarantees a real run has no side effects.

context