skip to content

What does the Gradle daemon do, and how do you disable it for a single build invocation?

level: juniorimportance: must knowfreq 60%

answer

  1. long-lived background JVM
  2. --no-daemon = single-use
  3. org.gradle.daemon=false
  4. --status / --stop
  5. warm JIT, cached config

basics

~10 s

The daemon is a long-lived background JVM that Gradle reuses across builds to avoid startup cost. Disable it for one build with --no-daemon, or permanently via org.gradle.daemon=false in gradle.properties.

solid answer

~40 s

The Gradle **daemon** is a persistent background JVM process that stays alive between invocations, keeping the JVM warm (JIT-compiled code), caching build configuration, and avoiding repeated JVM and Gradle bootstrap cost. Each build normally connects to a compatible idle daemon or spawns a new one. To disable it for a single run, pass `--no-daemon` on the command line: ``` ./gradlew build --no-daemon ``` That build runs in a **single-use** daemon: a foreground process that exits as soon as the build finishes. To disable it persistently, set `org.gradle.daemon=false` in `gradle.properties` (project or `~/.gradle/`), or export `GRADLE_OPTS="-Dorg.gradle.daemon=false"`. Conversely `--daemon` forces daemon use for one build.

code

bash · 9 lines
bash
# disable for one build
./gradlew build --no-daemon

# disable persistently
echo 'org.gradle.daemon=false' >> gradle.properties

# inspect / stop running daemons
./gradlew --status
./gradlew --stop

go deeper

for a junior

Know that the daemon is a reused background process and that --no-daemon / org.gradle.daemon=false turn it off.

for a middle

Explain the single-use daemon nuance, the three ways to disable, and precedence between flag and property.

for a senior

Tie disabling to JIT/warm-up trade-offs and know --status/--stop for diagnosing daemon state.

for a principal

Frame daemon-on vs daemon-off as a policy choice per environment (dev vs CI) and standardise it across teams.

## What the daemon is The **Gradle daemon** is a long-lived JVM process that Gradle launches in the background. Running a build via the launcher (`gradle`/`gradlew`) starts a thin client process that hands the work to a daemon. The daemon stays resident after the build ends so the *next* build can reuse it. ## Why a daemon exists Starting a fresh JVM is expensive: classloading, JIT warm-up, and Gradle's own bootstrap (loading plugins, building the model). By keeping a warm JVM around, the daemon: - skips JVM start-up on subsequent builds - benefits from **JIT** optimisation accumulated across builds (hot code is compiled to native) - keeps in-memory caches warm (e.g. resolved configuration) This is why a second build is usually much faster than the first. ## How to disable it There are three equivalent levers, from most to least scoped: 1. **Per-invocation flag** — `--no-daemon` (or its inverse `--daemon`). 2. **Property in `gradle.properties`** — `org.gradle.daemon=false` (project-level `gradle.properties` or the user-level `~/.gradle/gradle.properties`). 3. **JVM system property via env** — `GRADLE_OPTS="-Dorg.gradle.daemon=false"`. Precedence: a command-line flag wins over a property, and project properties layer with user-level ones. ## Single-use daemon `--no-daemon` does **not** mean "no JVM forked." Gradle still forks a worker JVM, but it runs as a **single-use daemon**: it executes exactly one build in the foreground and then terminates. So you still pay JVM start-up once, but nothing survives the build — no resident process, no cross-build reuse. ```bash # one build, no surviving process ./gradlew test --no-daemon # inspect / clean up daemons ./gradlew --status ./gradlew --stop ``` `--status` lists running daemons and their states (IDLE, BUSY); `--stop` gracefully shuts them down. ## Mental model Daemon = warm, reusable, fast for repeated local builds. `--no-daemon` = cold, single-shot, predictable for one-off and CI builds where nothing should outlive the job.

  • Does --no-daemon mean no separate JVM is forked at all?
    No. Gradle still forks a JVM, but it runs as a single-use daemon that executes exactly one build in the foreground and then exits, so nothing survives the build.
  • How do you see whether daemons are currently running?
    `./gradlew --status` lists running daemons with their PID and state (IDLE/BUSY); `./gradlew --stop` shuts them down gracefully.

A daemon is like leaving your car engine running between short errands so you skip the cold start each time; --no-daemon is turning the engine off completely after one trip.

saying these in an interview costs you the question

  • Claiming --no-daemon runs the build inside the launcher with no forked JVM at all.
  • Saying the daemon is just a thread inside the gradlew client rather than a separate process.

context