Open-Source Wikis

/

Kotlin

/

Compiler

/

Daemon

JetBrains/kotlin

Daemon

Active contributors: Ilya Chernikov, Dmitriy Novozhilov, Alexander Udalov

The Kotlin Compile Daemon is a long-running JVM that hosts the compiler in-process and accepts compile requests over a local RPC channel. It exists to amortize JVM startup and class-loading costs across many compiles in a session — a necessity for any reasonably interactive build experience.

Purpose

Run the Kotlin compiler in a persistent JVM. Build tools (KGP, the Maven plugin, JPS, the IDE) connect to the daemon, send a compile request with arguments and source paths, and receive results. Compared to spawning a fresh kotlinc per compile, this saves roughly 1–3 seconds of JVM startup plus class-loading and warmup.

Directory layout

compiler/daemon/                Daemon protocol, server, and client
compiler/daemon/.../client/     Client-side wrapper used by build tools
compiler/daemon/.../server/     Server (the long-running JVM)
compiler/daemon/.../common/     Shared types (request/response)
compiler/incremental-compilation-impl/  Incremental compilation engine used by daemon and JPS
compiler/preloader/             Classloader / class-warmup logic the daemon relies on

Key abstractions

Type Where Role
CompileService compiler/daemon/.../common/CompileService.kt The RMI/JMX-style interface the daemon exposes.
KotlinCompilerClient compiler/daemon/.../client/KotlinCompilerClient.kt The client wrapper used by build tools.
KotlinCompileDaemon compiler/daemon/.../server/KotlinCompileDaemon.kt The daemon main class.
IncrementalCompilation compiler/incremental-compilation-impl/... The incremental engine (lookup tracking, dirty-set propagation).
Preloader compiler/preloader/... Classloading helper that pre-warms heavy intellij-core classes.

How clients talk to the daemon

sequenceDiagram
    participant Client as Client (KGP)
    participant Daemon as Compile Daemon JVM
    Client->>Daemon: discover daemon (port file in temp dir)
    alt no daemon running
        Client->>Daemon: spawn new JVM (KotlinCompileDaemon main)
        Daemon-->>Client: writes port file
    end
    Client->>Daemon: connect over RMI/JMX
    Client->>Daemon: leaseSession(arguments, sources)
    Daemon->>Daemon: run compile
    Daemon-->>Client: stream messages
    Daemon-->>Client: result (success/failures)
    Client->>Daemon: releaseSession

Discovery is via a directory of "port files" in the system temp directory. Each running daemon writes a small file naming the port and the arguments it was configured with. Clients pick the one whose configuration matches and start a new daemon if no compatible one exists.

Incremental compilation

compiler/incremental-compilation-impl/ is a separate but related piece. It tracks which Kotlin classes were touched, which downstream classes need recompiling, and how to merge incremental outputs. The daemon hosts the incremental engine in-memory across compiles, which is the second major win after JVM warm-up.

The same incremental engine is used by JPS (the IntelliJ build system) — it does not require the daemon, but the daemon path is the most polished consumer.

Sandboxing and JDK toolchain

The daemon validates that its JDK matches the configured target JDK. Mismatches force the build tool to spawn a different daemon. JDK toolchain selection logic lives in compiler/build-tools/kotlin-build-tools-jdk-utils/ and is shared with BTAPI.

Logs and metrics

Each daemon writes a per-session log under the system temp directory. The logs are useful when investigating "why did my build take that long?" — they contain incremental analysis decisions, classpath snapshots, and timing.

compiler/build-tools/kotlin-build-statistics/ collects metrics from the daemon and forwards them to the build tool.

Lifecycle

Daemons time out and shut down after an idle period. The default is configurable (KOTLIN_DAEMON_IDLE_TIMEOUT, accessible via JVM system properties). KGP also exposes options to bound how long a daemon survives.

When the daemon is bypassed

  • kotlinc from a shell — no daemon by default.
  • KGP with kotlin.compiler.execution.strategy=in-process — runs in-Gradle, no daemon.
  • The IDE (intellij-community) — uses a different in-IDE compile path that goes through the in-IDE compile service, not this daemon.

Integration points

  • Clients: KGP, the Maven plugin, JPS, the standalone kotlinc (via --daemon flag).
  • Server: the daemon itself, which depends on compiler/cli/, compiler/preloader/, and compiler/incremental-compilation-impl/.
  • Co-traveler: compiler/build-tools/kotlin-build-tools-cri-impl/ (compile request infrastructure) and compiler/build-tools/kotlin-build-tools-jdk-utils/.

Where to start

Daemon protocol changes are rare and risky — the daemon must be backward-compatible across Kotlin versions because clients (KGP) ship at a different cadence. Read compiler/daemon/AGENTS.md if it exists, otherwise look at recent commits with the [Daemon] prefix.

See build-tools.md for the BTAPI surface and tools/kotlin-gradle-plugin.md for the daemon's busiest client.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Daemon – Kotlin wiki | Factory