website/docs/guides/daemon.mdx
import VersionLabel from '@site/src/components/Docs/VersionLabel';
<VersionLabel version="2.2.0" header />As workspaces grow in size, the time spent building
project and task graphs becomes a noticeable bottleneck. Every
moon CLI invocation rebuilds these graphs from scratch, even when nothing has changed since the
last run. The daemon solves this by running a background server process that keeps the workspace
graph hot in memory, watches for file changes, and rebuilds only when necessary. This eliminates
redundant work and significantly improves CLI response times, especially in larger workspaces with
hundreds or thousands of projects/tasks.
:::caution
This feature is currently unstable and must be explicitly enabled. Its behavior and configuration may change in future releases.
:::
To enable the daemon, set the unstable_daemon setting in
.moon/workspace.yml.
unstable_daemon: true
Alternatively, you can enable it via the MOON_DAEMON environment variable without modifying your
configuration. This is useful for trying it out before committing to the change.
MOON_DAEMON=true moon run :build
When the daemon is enabled, the first moon CLI command you run automatically spawns a background
server process. This process detaches from the terminal and continues running after the command
completes. Subsequent CLI invocations connect to the running daemon instead of starting fresh.
The daemon communicates with CLI processes over a local IPC channel — Unix domain sockets on
macOS/Linux, and named pipes on Windows. All daemon files (PID, socket, and logs) are stored in
.moon/cache/daemon.
If the daemon fails to start or is unavailable, the CLI falls back to building graphs in-process as it normally would without the daemon. You won't see an error — the CLI simply proceeds without the performance benefit.
To keep the in-memory graph up to date, the daemon watches the workspace root recursively for file system changes. Events are debounced (coalesced within a short window) to avoid redundant rebuilds during rapid edits.
The following directories are always ignored by the watcher:
.git, .svn, node_modules.moon/cache, .moon/dockerChanges to the following files and directories trigger an asynchronous graph rebuild:
.prototools — reloads toolchain configuration.moon/workspace.* — reloads workspace settings.moon/toolchains.* — reloads toolchain plugins.moon/extensions.* — reloads extension plugins.moon/tasks/**/* — reloads task inheritancemoon.* config files in project directories — reloads project configurationBecause rebuilds happen asynchronously in the background, the daemon remains responsive to new CLI connections while a rebuild is in progress.
The moon daemon command provides subcommands for managing the daemon's
lifecycle. In most cases you won't need these — the daemon starts automatically and stays out of the
way — but they're useful for debugging or manual control.
$ moon daemon start
Starts the daemon if it's not already running. If a daemon is already running for this workspace,
the existing process is reused. You typically don't need to run this manually, as the daemon
auto-starts with any moon command when enabled. See
moon daemon start.
$ moon daemon stop
Stops the daemon gracefully. If the daemon does not shut down within a few seconds, it will be
forcefully killed. Daemon files (PID, socket) are cleaned up automatically. See
moon daemon stop.
$ moon daemon restart
Stops the running daemon and starts a new one. This is useful after manual configuration changes, or
if the daemon's cached state seems stale. See moon daemon restart.
$ moon daemon status
Displays information about the running daemon, including its process ID, uptime, socket/pipe
endpoint, and file paths for the PID and log files. See
moon daemon status.
$ moon daemon logs
Tails the daemon's log file in real time. The daemon must be running for this command to work. The
log file is located at .moon/cache/daemon/server.log and contains detailed trace-level output. See
moon daemon logs.
unstable_daemon: true is set in
.moon/workspace.yml, or that the MOON_DAEMON environment variable is
set.moon daemon status..moon/cache/daemon and try again.If tasks or projects appear to be missing or outdated despite config changes, the file watcher may
have missed an event. Run moon daemon restart to force a fresh graph
build.
The daemon writes detailed logs to .moon/cache/daemon/server.log. Use
moon daemon logs to tail this file, or open it directly in an editor.
After upgrading moon to a new version, restart the daemon with
moon daemon restart. A running daemon from a previous version may
behave unexpectedly or return stale data. We'll attempt to automate this when applicable.
The daemon is designed for local development where a persistent background process can be reused across multiple CLI invocations. In CI environments, where each run starts fresh, the daemon provides no benefit since there's no long-lived process to connect to. Enabling it in CI won't cause harm, but it won't improve performance either.