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?
answer
- flag > user props/GRADLE_OPTS > project props
- --no-daemon overrides property
- dev wants on, CI wants off
- user-level ~/.gradle on agent
- don't bake CI-only into repo file
basics
~20 sThe 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.
solid answer
~40 sCommand-line flags take **precedence** over `gradle.properties`, so `--no-daemon` overrides `org.gradle.daemon=true` for that invocation: the build runs in a single-use daemon and exits. For managing the setting across environments, prefer keeping daemon policy out of decisions that should differ by environment: - Keep the **project** `gradle.properties` developer-friendly (daemon enabled, the default) so local dev stays fast. - Have CI **override per-invocation** with `--no-daemon`, or set `org.gradle.daemon=false` via the **user-level** `~/.gradle/gradle.properties` on the agent, or via `GRADLE_OPTS="-Dorg.gradle.daemon=false"` as an env var. The layering order (lowest to highest): project `gradle.properties` < user `~/.gradle/gradle.properties` and `GRADLE_OPTS` < command-line flag. This lets one repo serve both fast local builds and clean CI without hard-coding a CI-only choice into the shared file.
code
bash · 4 lines# committed gradle.properties: org.gradle.daemon=true (dev-friendly default)
# CI overrides without touching the file:
./gradlew build --no-daemon
# or on the agent: export GRADLE_OPTS="-Dorg.gradle.daemon=false"go deeper
Know the flag beats the property for a single build.
Recite the precedence order and pick the right layer for an environment-specific override.
Design the local-vs-CI split so the committed file stays dev-friendly and CI overrides cleanly.
Standardise where each class of setting lives (repo vs agent vs env) so behaviour is predictable across teams.
## What wins, and why Gradle resolves the daemon setting from several layers. From lowest to highest precedence: 1. **Project `gradle.properties`** (checked into the repo). 2. **User `~/.gradle/gradle.properties`** and the `GRADLE_OPTS` environment variable (`-Dorg.gradle.daemon=...`). 3. **Command-line flag** (`--daemon` / `--no-daemon`). So with `org.gradle.daemon=true` in the project file but `--no-daemon` on the command line, the **flag wins** — that build is single-use. The property is not an error; it's simply a lower-priority default. ## The management problem Daemon policy is one of the settings that *should* differ by environment: developers want it **on** (fast repeated builds), CI often wants it **off** (clean, leak-free). Hard-coding `org.gradle.daemon=false` in the committed project file would slow every local build. Hard-coding `true` is fine as the default but you still need CI to override. ## Patterns that work ```bash # Pattern A: CI overrides per-invocation (project file stays dev-friendly) ./gradlew build --no-daemon ``` ```properties # Pattern B: set it on the agent via user-level gradle.properties # ~/.gradle/gradle.properties on the CI runner org.gradle.daemon=false ``` ```bash # Pattern C: env var on the agent export GRADLE_OPTS="-Dorg.gradle.daemon=false" ./gradlew build ``` All three keep the **committed** `gradle.properties` honest for local developers while letting CI impose its own policy at a higher precedence layer. ## Guidance - Put environment-neutral, project-wide settings in the committed `gradle.properties`. - Put **environment-specific** choices (like CI daemon-off) in the per-invocation flag, the user-level file on the agent, or env — never bake a CI-only value into the shared repo file unless the whole team agrees it is the universal default. - Remember precedence when debugging "my setting isn't taking effect": a higher layer is overriding it.
- Where would you put org.gradle.daemon=false so it applies on a CI agent but not in the committed repo?In the agent's user-level ~/.gradle/gradle.properties, or via GRADLE_OPTS, or by passing --no-daemon per invocation — all higher precedence than the project file and not committed to the repo.
- My gradle.properties says daemon=false but builds still seem to reuse a daemon — why?A higher-precedence layer is overriding it: a --daemon flag, a user-level gradle.properties, or GRADLE_OPTS. Check the precedence order to find the winning source.
saying these in an interview costs you the question
- Claiming the gradle.properties value overrides the command-line flag.
- Committing a CI-only org.gradle.daemon=false into the shared project file, silently slowing all local builds.
- Not knowing the user-level ~/.gradle file exists as a per-machine override layer.