> ## Documentation Index
> Fetch the complete documentation index at: https://docs.open4rena.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# The o4 daemon

> Start, stop, and check the experimental o4 background daemon.

The o4 daemon is a long-running background process that can host agent
sessions and serve them to clients over a Unix socket. It runs the same agent
runtime that o4 sessions use, with a socket in front of it.

<Warning>
  The daemon is experimental. In o4 0.2.74, nothing starts it for you, and
  interactive sessions, print mode (`o4 -p`), and `o4 resume` all run their
  sessions inside the o4 process without using the daemon. You only need the
  commands on this page if you are building or testing a client for it.
</Warning>

## Commands

| Command | What it does |
| - | - |
| `o4 daemon start` | Start the daemon in the background if it isn't running |
| `o4 daemon status` | Show whether the daemon is running |
| `o4 daemon stop` | Stop the running daemon |
| `o4 daemon restart` | Stop the daemon if it's running, then start it |

The commands take no options other than `--help`.

### Start

`o4 daemon start` starts the daemon as a detached background process and
waits up to 5 seconds for it to answer on its socket:

```text theme={null}
$ o4 daemon start
daemon started (pid 3726)
```

If a daemon is already running for the same data folder, o4 doesn't start a
second one:

```text theme={null}
$ o4 daemon start
daemon already running (pid 3726, protocol v1)
```

If the daemon stopped without cleaning up, for example after a crash, `start`
clears the leftover files first.

If the daemon doesn't answer within 5 seconds, `start` prints
`Error: the daemon did not answer within 5s; see` followed by the path of
`daemon.log`, and exits with code `1`. Check that log for the reason. Other
errors also exit with code `1`.

### Status

```text theme={null}
$ o4 daemon status
running
  pid: 3726
  version: 0.2.74
  protocol: v1
  socket: /Users/you/.o4/daemon/o4.sock
```

`o4 daemon status` exits with code `0` when the daemon is running and `3`
when it isn't, so scripts can check it without reading the output:

```bash theme={null}
if o4 daemon status > /dev/null; then
  echo "daemon is running"
fi
```

### Stop and restart

`o4 daemon stop` asks the daemon to shut down with `SIGTERM`. If it's still
running after the grace period (10 seconds by default), o4 sends `SIGKILL`.

```text theme={null}
$ o4 daemon stop
daemon stopped (pid 3726)
```

When no daemon is running, `stop` prints `daemon is not running` and exits
with code `3`.

`o4 daemon restart` runs `stop` and then `start`, and prints what each one
prints. If the daemon isn't running, it prints `daemon is not running`, starts
it, and exits with code `0`:

```text theme={null}
$ o4 daemon restart
daemon stopped (pid 3726)
daemon started (pid 3740)
```

### Run in the foreground

`o4 daemon serve` runs the daemon in your terminal instead of in the
background. It's the command `start` launches, and it isn't listed in
`o4 daemon --help`. It prints nothing while it runs. `o4 daemon status` and
`o4 daemon stop` work with it as usual, so stop it from another terminal with
`o4 daemon stop`.

If a daemon is already running for the data folder, `serve` exits with code
`1`:

```text theme={null}
$ o4 daemon serve
Error: a daemon is already running for this data dir (pid 3726)
```

If you stop `serve` with `Ctrl+C`, it leaves its socket and `daemon.pid`
behind. `status` then reports `not running`, and the next `start` or `serve`
clears the leftover files.

## Files

The daemon keeps its files in a `daemon` folder inside the o4 data folder,
which is `~/.o4` unless the `O4_AGENT_RUNTIME_DATA_DIR` environment variable
points somewhere else. Each data folder has at most one daemon.

| File | Purpose |
| - | - |
| `~/.o4/daemon/o4.sock` | The Unix socket clients connect to |
| `~/.o4/daemon/daemon.pid` | The daemon's process ID and start time |
| `~/.o4/daemon/daemon.lock` | A lock that stops two `start` commands from racing |
| `~/.o4/daemon/daemon.log` | The daemon's log output |

The folder is readable only by you, and the socket has owner-only
permissions. The daemon also closes any connection from a process running as
a different user. It has no network listener.

## Settings

You can tune the daemon in the `[daemon]` table of your user config file,
`~/.o4/config.toml`:

```toml theme={null}
[daemon]
stop_grace_ms = 5000
max_sessions = 32
```

| Setting | Default | What it does |
| - | - | - |
| `stop_grace_ms` | `10000` | Milliseconds `o4 daemon stop` and `o4 daemon restart` wait after `SIGTERM` before sending `SIGKILL` |
| `max_sessions` | `64` | The most sessions the daemon hosts at once; it refuses new ones past this |
| `client_queue_max_events` | `4096` | Events queued for one client connection. A client that falls this far behind is disconnected; the daemon and other clients carry on |
| `pressure_rss_mb` | `4096` | Memory use, in MiB, above which the daemon refuses new sessions |
| `pressure_open_files` | `2048` | Open files above which the daemon refuses new sessions |
| `enabled` | `false` | Accepted, but has no effect in 0.2.74: nothing starts the daemon automatically |
| `idle_unload_secs` | `3600` | Accepted, but the daemon doesn't read it in 0.2.74 |

The daemon reads these settings when it starts, so run `o4 daemon restart`
after you change them. `stop_grace_ms` is read by the `stop` command itself.
If `~/.o4/config.toml` can't be read, the daemon commands use the defaults.

o4 also reads `[daemon]` from the managed config, `~/.o4/managed/config.toml`,
and a key there wins over the same key in your file. o4 ignores a `[daemon]`
table in a project's `.o4/config.toml` or `.o4/config.local.toml`, with a
warning in the log. The settings always come from `~/.o4`, even when
`O4_AGENT_RUNTIME_DATA_DIR` points the daemon's files somewhere else. See
[Configuration files](/configuration/overview) and the
[configuration reference](/reference/configuration#daemon).
