skip to content

What is the Gradle daemon registry, where does it live, and how do `--status`/`--stop` use it?

level: seniorimportance: should knowfreq 35%

answer

  1. registry.bin per version
  2. GRADLE_USER_HOME/daemon/<version>/
  3. address + PID + start opts + state
  4. client picks compatible IDLE daemon
  5. stale entries pruned (cache)

basics

~10 s

The registry is a small binary file (registry.bin) under GRADLE_USER_HOME/daemon/<version>/ tracking each daemon's address, PID and state. --status reads it; builds and --stop update it; dead entries are pruned automatically.

solid answer

~40 s

Each Gradle version keeps a **daemon registry** at `GRADLE_USER_HOME/daemon/<gradleVersion>/registry.bin` (default `~/.gradle/daemon/...`). It's the shared index that lets the client and daemons find each other: every entry records a daemon's communication address, PID, the JVM/build options it was started with, and its current state (IDLE/BUSY/etc.). When you start a build, the client reads the registry to find a **compatible** idle daemon to reuse; if none matches it spawns one and registers it. `gradle --status` simply renders the registry; `gradle --stop` reads it to message each daemon. State transitions (a daemon going BUSY then IDLE, or exiting) are written back. Because processes can die abruptly, Gradle treats the registry as a cache: stale entries pointing at dead PIDs are pruned on the next access. Per-version subdirectories are why daemons of different versions don't see each other.

code

bash · 5 lines
bash
# inspect the registry location
ls "${GRADLE_USER_HOME:-$HOME/.gradle}"/daemon
# e.g. -> 8.7/  8.5/   (one dir per version)
ls "${GRADLE_USER_HOME:-$HOME/.gradle}"/daemon/8.7
# registry.bin  daemon-12345.out.log ...

go deeper

for a junior

Know there's a file under ~/.gradle/daemon that tracks running daemons.

for a middle

Know the path and that it stores PID/state and backs --status/--stop.

for a senior

Explain per-version layout, compatibility matching on start options, and stale-entry pruning.

for a principal

Use it to reason about shared-host daemon sprawl, version segregation, and clean-reset strategies in tooling.

## What problem the registry solves The daemon runs as a **separate process** from the client you launch on the command line. For reuse to work, the client must discover already-running daemons, decide which (if any) it can reuse, and be able to message them — including for `--stop`. The **daemon registry** is the rendezvous point that makes this possible. ## Location and layout ``` $GRADLE_USER_HOME/ # default: ~/.gradle daemon/ 8.7/ registry.bin # the registry for 8.7 daemons daemon-<pid>.out.log # per-daemon log 8.5/ registry.bin ``` The registry is **per Gradle version** — that's the structural reason `--status` and `--stop` only see same-version daemons: each version reads its own `daemon/<version>/registry.bin`. ## What an entry holds Each registered daemon contributes an entry with: - a **communication address** (how the client connects to it), - the **PID**, - the **start options** — JVM args, encoding, etc. — used for *compatibility* matching, - the current **state** (IDLE, BUSY, CANCELED, STOPPED). ## How the commands use it - **A build invocation** reads the registry, filters for an IDLE daemon whose start options are compatible with what this build needs, and reuses it; otherwise it spawns and registers a fresh one. While building, the daemon marks itself BUSY in the registry, then IDLE again on completion. - **`gradle --status`** reads and prints the registry contents. - **`gradle --stop`** reads the registry and sends a graceful stop to each compatible entry; exiting daemons remove themselves. ## Self-healing Daemons can crash or be `kill`ed, leaving entries that point at dead PIDs. Gradle treats the registry as a best-effort cache: on the next access it **prunes** entries it can no longer reach, which is why a `--status` right after a crash may differ from one a moment later. Manually deleting the `daemon/<version>` directory is a blunt reset, though `--stop` plus letting Gradle re-create it is cleaner. ## Why a senior should know this It explains otherwise-confusing behaviour: 'why doesn't `--stop` kill that daemon?' (different version → different registry), 'why are there five daemons?' (incompatible start options spawned new entries rather than reusing), and where to look (`daemon/<version>/`) when diagnosing daemon issues.

  • Why do `--status` and `--stop` only see same-version daemons?
    The registry is stored per Gradle version under `daemon/<version>/registry.bin`, so each version reads only its own registry.
  • Why might several daemons exist for one version?
    Builds requesting incompatible start options (different JVM args/encoding) can't reuse an existing daemon, so Gradle spawns and registers additional ones.
  • What happens to a registry entry whose daemon was killed?
    It becomes stale; Gradle treats the registry as a cache and prunes unreachable entries on the next access.

saying these in an interview costs you the question

  • Describing the registry as a human-editable text/config file — it's a binary cache.
  • Thinking one global registry covers all Gradle versions.

context