# Boot configuration

What a simulator starts with, in what order, and which feature each boot input needs; every environment variable and flag the simulator binary reads.

A [simulator](https://www.rystic.ai/docs/concepts/glossary.md#simulator) binary reads its starting state, clock and schedule from flags and environment variables. `rystic run` sets most of them from its own flags; a container or the bare binary takes them directly.

## Boot inputs

A simulator boots empty unless one of these names a starting state:

1. `--scenario` or `RYSTIC_SCENARIO`: a [named scenario](https://www.rystic.ai/docs/concepts/glossary.md#named-scenario) the build ships.
2. `--seed` or `RYSTIC_SEED`: a seed file.
3. `--inject` or `RYSTIC_INJECT`: a [timeline](https://www.rystic.ai/docs/timelines.md) file, the `POST /_rystic/inject` body or one event per line. `rystic run --inject` sets it. With `--tape`, Kalshi runs it on tape time: [Kalshi → Script events on tape time](https://www.rystic.ai/docs/simulators/kalshi/features/tape-replay.md#script-events-on-tape-time).
4. `RYSTIC_PACE` and `RYSTIC_CLOCK`: [pacing](https://www.rystic.ai/docs/concepts/reset-and-determinism.md#pacing) and the [starting clock](https://www.rystic.ai/docs/concepts/reset-and-determinism.md#the-clock).
5. `RYSTIC_NETWORK`: a [network profile](https://www.rystic.ai/docs/network-profiles.md#at-boot).

The simulator lands the boot scenario, then `--seed`, then `RYSTIC_SEED`, then the `--inject` schedule, which replaces a boot scenario's own events.

Each input needs a feature, as a route does. `--scenario` needs `scenarios`; `--seed`, `--inject`, `RYSTIC_CLOCK` and `RYSTIC_PACE` above `0` need `state_set`; `RYSTIC_NETWORK` needs `faults`. Pro and Enterprise include all three. On a plan without one, the input stops the simulator before it serves, and `rystic run` exits non-zero:

```text
RYSTIC_NETWORK needs the "faults" feature, which this plan does not include; upgrade at https://www.rystic.ai/pricing
```

Any `RYSTIC_NETWORK` value counts, `off` included (`run --network` sets it). A boot seed file that carries a `network` key stops it the same way (`the boot seed <path> carries a network profile, and needs the "faults" feature, …`). Enterprise has no gate.

## The boot seed file

A boot seed file (`--seed`, `RYSTIC_SEED`) holds either shape `POST /_rystic/seed` takes: a bare register map, or a [scenario file](https://www.rystic.ai/docs/concepts/worlds.md#two-shapes) marked by its top-level `seed` object. A scenario file's `events` read their offsets from the file's `clock`.

A `network` in a boot seed file takes the `POST /_rystic/network` body, not a bare profile. It installs as if you had posted it, so it outlasts `reset`. Its credential bindings and events leave on `reset`.

`rystic scenario save <instance> <file>`, and the MCP server's `save_world`, write a running simulator's state as a scenario file, so a state you drove by hand boots again with `--seed`: [Save and restore without MCP](https://www.rystic.ai/docs/concepts/snapshots-and-test-cases.md#without-mcp).

## Environment variables

Every simulator binary reads these, and the image passes them through. `rystic run` sets the first seven from its flags. The CLI's own variables are on [the CLI page](https://www.rystic.ai/docs/cli.md#files-and-environment).

| Variable | Default | Meaning |
|---|---|---|
| `RYSTIC_ADDR` | `:8080` | listen address; `rystic run` sets it from `--port` |
| `RYSTIC_SCENARIO` | unset | boot scenario; `--scenario` wins |
| `RYSTIC_SEED` | unset | boot seed or scenario file, applied after `--seed` |
| `RYSTIC_NETWORK` | unset | `off`, `on`, or a profile file ([At boot](https://www.rystic.ai/docs/network-profiles.md#at-boot)). Needs `faults` |
| `RYSTIC_INJECT` | unset | a timeline file, the `POST /_rystic/inject` body or one event per line; `--inject` wins. Needs `state_set` |
| `RYSTIC_PACE` | unset | simulated seconds the clock moves per wall second ([Pacing](https://www.rystic.ai/docs/concepts/reset-and-determinism.md#pacing)); unset or `0` leaves the clock manual. Above `0` it needs `state_set` |
| `RYSTIC_CLOCK` | unset | the RFC3339 instant the clock starts at, over a boot scenario's own clock, and that every reset returns to (`rystic run --clock`). Needs `state_set` |
| `RYSTIC_EGRESS_RETAIN` | [Retention](https://www.rystic.ai/docs/concepts/observing.md#retention) | egress frames and calls kept before the oldest drop; `0` is unbounded |
| `RYSTIC_EVENTS` | `private,writes,control` | events printed to stdout: `on`, `off`, `all`, or a list of `private`, `public`, `writes`, `reads`, `control`; `--events` wins |
| `RYSTIC_SEED_GATE` | warn | `reject` refuses a seed with missing required fields instead of serving it with a warning; `off` skips the check |
| `RYSTIC_WEBHOOK_DELIVERY` | unset | `on` lets the simulator deliver its webhooks over HTTP; otherwise they land only in the egress log ([Webhooks](https://www.rystic.ai/docs/webhooks.md)) |
| `RYSTIC_ADMIN_TOKEN` | unset | when set, a control route needs it in `X-Rystic-Admin-Token` or the `rystic_admin_token` cookie. That covers every `/_rystic/` route but `/_rystic/version` and signed file URLs, plus `/_replay/*` and a simulator's own routes such as `/_settle` ([The admin token](https://www.rystic.ai/docs/shared-simulators.md#the-admin-token)) |
| `RYSTIC_ACTION_LOG` | unset | a file the simulator appends one JSON line to per state change ([The action log](https://www.rystic.ai/docs/shared-simulators.md#the-action-log)) |
| `RYSTIC_GATEWAY_TOKEN` | unset | when set, every request, vendor and control alike, must carry `X-Rystic-Gateway-Token` with this value or gets `403`. For a simulator behind your own proxy on a network agents can reach. `rystic run`'s readiness probe and the image's `HEALTHCHECK` send no header, so use it with the bare binary, or a container with its own health check (`run -d` times out, exit 7) |
| `RYSTIC_PRESERVE_SERVICE_URLS` | unset | `1` keeps the vendor's hostnames in URLs the simulator returns, for a [gateway](https://www.rystic.ai/docs/concepts/glossary.md#gateway) that routes those hosts to it |
| `RYSTIC_TOKEN` | unset | Pro: the API key the simulator registers with |
| `RYSTIC_REGISTER_WAIT` | `10m` | how long a simulator on Pro retries reaching Rystic at start; `0` tries once |
| `RYSTIC_LEASE_CACHE` | your config directory's `rystic/leases` | where the last lease is kept, which allows [one offline start](https://www.rystic.ai/docs/licensing.md#offline-and-outages) |
| `RYSTIC_LEASE_URL` | `https://lease.rystic.ai` | the lease server |
| `RYSTIC_LEASE_VERBOSE` | unset | `true` prints a line per check-in; `rystic run -v` sets it |
| `RYSTIC_LICENSE` | `./rystic-license.json` | Enterprise: a license file path, or the license itself, JSON or base64 |

Kalshi adds its replay, live-feed and key variables: [Kalshi → Flags and environment](https://www.rystic.ai/docs/simulators/kalshi/features/live-feed-settings.md#flags-and-environment).

## Flags

The binary takes these flags, with one or two leading hyphens, as `--flag value` or `--flag=value`:

| Flag | Meaning |
|---|---|
| `--scenario <name>` | boot scenario |
| `--seed <file>` | boot seed or scenario file |
| `--inject <file>` | boot timeline |
| `--addr <host:port>` | listen address |
| `--events <scope>` | stdout event scope |
| `--list-scenarios` | print the scenarios and exit |
| `--dump-scenario <name>` | print a named scenario as a scenario file and exit; needs `scenarios` |
| `--routes` | print the vendor routes, as `GET /_rystic/routes` returns them, and exit |
| `--describe` | print the simulator's description and exit |
| `--version` | print the identity and exit |
| `--health[=<addr>]` | probe a running simulator and exit 0 if it answers; the image's `HEALTHCHECK` |

---

Source: https://www.rystic.ai/docs/boot-configuration · Markdown: https://www.rystic.ai/docs/boot-configuration.md
