skip to content

Disabling the Daemon (--no-daemon, CI)

Turning the daemon off or constraining it, and why ephemeral CI agents commonly do. Interviewers ask because --no-daemon trades startup time for avoiding orphaned processes and memory bloat.

on this pageshow

questions

5

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

open as a page

Why is disabling (or constraining) the Gradle daemon a common recommendation on ephemeral CI agents?

level: middleimportance: must knowfreq 65%

basics

~10 s

On throwaway CI agents the daemon never gets reused, so it brings no speed-up but risks orphaned processes and memory bloat. Disabling it gives a clean, predictable single-use JVM per job.

open as a page

A repo's gradle.properties has org.gradle.daemon=true but CI runs ./gradlew build --no-daemon. What happens, and how should you manage these settings across local and CI?

level: middleimportance: should knowfreq 30%

basics

~20 s

The command-line --no-daemon wins for that build — it runs single-use despite the property. Best practice: leave the property at the developer-friendly default and let CI override per-invocation, or set it via a user-level/env config in CI.

open as a page

A self-hosted runner pool reuses agents across many Gradle jobs. How do you decide whether to disable or keep (but constrain) the daemon?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Measure reuse. If agents run many back-to-back Gradle builds, keeping the daemon speeds them up — but cap its memory and prevent accumulation. If reuse is rare or limits are tight, disable it for predictability.

open as a page

Even with the daemon disabled, how can Gradle leave processes behind on a CI agent, and how do you ensure a clean exit?

level: seniorimportance: should knowfreq 40%

basics

~20 s

A build forks more than the main JVM — worker daemons for compilation/tests. With the build daemon disabled you still want these to exit; use --no-daemon plus killing stray Java processes or running in a destroyed-per-job container.

open as a page