Skip to main content
The daemon is the background process that powers your Comis installation. Think of it as the engine running behind the scenes — it manages your agents, handles messages, runs scheduled tasks, and keeps everything connected. You start it once and it runs continuously until you stop it.

What the Daemon Does

When the daemon is running, it handles four main responsibilities:
  • Manages agent connections — Keeps your AI agents online and ready to respond to messages across all connected channels.
  • Processes messages — Routes incoming messages to the right agent, sends them to your AI provider, and delivers the response back to the user.
  • Runs scheduled tasks — Executes cron jobs, heartbeat health checks, and any tasks your agents have scheduled for themselves.
  • Monitors system health — Watches disk space, CPU, memory, and other vital signs, alerting you if something needs attention.

Starting Up

When you start the daemon, it goes through a careful initialization sequence: loading your configuration, connecting to channels, starting agents, and beginning health monitoring. The whole process typically takes one to three seconds. When it finishes, you will see a startup banner in the logs:
This banner tells you everything important at a glance: which agents are running, which channels are connected, what port the gateway is listening on, and how long startup took.
Look for "Comis daemon started" in the logs — if you see it, everything initialized successfully. If you see FATAL: instead, check the Recovering from Problems section below or the Troubleshooting page.

What Happens During Startup

Behind the scenes, the daemon runs through these steps in order:
  1. Loads environment variables from ~/.comis/.env
  2. Decrypts any stored secrets (API keys, tokens)
  3. Hardens file permissions on the data directory (~/.comis/)
  4. Reads configuration from the paths in COMIS_CONFIG_PATHS (default: ~/.comis/config.yaml) — for the full config-path syntax, see Configuration
  5. Sets up logging (file transport, per-module log levels)
  6. Initializes observability (token tracking, latency recording)
  7. Opens the memory database (SQLite with full-text search)
  8. Creates agent executors with their configured models
  9. Starts channel adapters (Telegram, Discord, Slack, etc.)
  10. Starts the scheduler (cron jobs, heartbeat monitoring)
  11. Launches the gateway server (HTTP, WebSocket, web dashboard)
  12. Registers graceful shutdown handlers
After step 12, the daemon saves a copy of the working configuration as a “last-known-good” snapshot (more on this in Recovering from Problems).

Running

Once started, the daemon runs continuously in the background. It processes messages as they arrive, runs health checks at regular intervals (every 5 minutes by default), and collects system metrics every 30 seconds. You do not need to interact with the daemon while it is running — it handles everything automatically. To check on it, view the logs or visit the Web Dashboard.

Shutting Down

When you stop the daemon (by sending a stop signal like SIGTERM), it performs a graceful shutdown. This means it does not just cut everything off — it carefully stops each component in the right order to avoid losing data or leaving connections open. Here is what the shutdown sequence looks like in the logs:
The shutdown follows this order:
  1. Session summary — Logs total executions, cost, and token usage for the session.
  2. Graph coordinator — Stops any running multi-agent pipelines.
  3. Sub-agent runner — Drains active sub-agent tasks.
  4. Cron schedulers — Stops scheduled jobs.
  5. Channel adapters — Disconnects from messaging platforms (no new messages accepted).
  6. Heartbeat runner — Stops health checks.
  7. Gateway server — Closes HTTP and WebSocket connections.
  8. Observability — Removes event subscriptions.
  9. Memory database — Closes the SQLite database cleanly.
The daemon waits up to 30 seconds for everything to stop cleanly. Active conversations will finish processing before shutdown completes. If a component takes too long, the daemon logs a timeout warning and forces an exit.
The final log line confirms a clean shutdown:

Recovering from Problems

Last-Known-Good Config

Every time the daemon starts successfully, it saves a copy of the working configuration file as a “last-known-good” snapshot. If you make a config change that prevents the daemon from starting, you can use this snapshot to recover. When a startup failure occurs due to a bad config change, you will see output like this:
The daemon tells you exactly how to recover — look for “last-known-good config available” in the error output. Follow the instructions it gives you, then restart the daemon.
To restore the last working configuration:
1

Copy the last-known-good config

2

Restart the daemon

3

Verify it started

Check the logs for "Comis daemon started" to confirm the recovery worked.

Common Startup Errors

If the daemon fails to start, the error message tells you what went wrong: For a complete list of error messages and solutions, see the Troubleshooting page.

Configuration

The daemon has several configuration options that control its behavior. Most users do not need to change these — the defaults work well for typical installations.

Logging

Understanding log output and controlling log levels.

Monitoring

What the daemon monitors and how alerts work.

systemd

Running the daemon as a Linux system service.

pm2

Managing the daemon with pm2 process manager.

Docker

Running the daemon in a Docker container.

Troubleshooting

Solving common startup and runtime problems.