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 onKey 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: releaseSessionDiscovery 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
kotlincfrom 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--daemonflag). - Server: the daemon itself, which depends on
compiler/cli/,compiler/preloader/, andcompiler/incremental-compilation-impl/. - Co-traveler:
compiler/build-tools/kotlin-build-tools-cri-impl/(compile request infrastructure) andcompiler/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.