# Reset and determinism

Every boot and every reset starts from the same state. The pinned clock, the fixed RNG seed, pacing, and what is and isn't deterministic.

The same starting state and the same requests give byte-identical ids, timestamps and events, run after run. The examples use the Lob simulator; every simulator takes the same calls.

## The loop

```bash
curl -s -X POST localhost:$PORT/_rystic/reset                 # empty; ids and clock rewound
curl -s -X POST localhost:$PORT/_rystic/seed -d @world.json   # or POST /_rystic/scenario
# ... run your code ...
curl -s localhost:$PORT/_rystic/inspect                       # assert exact records
curl -s localhost:$PORT/_rystic/egress                        # assert exact events
```

[Worlds and seeding](https://www.rystic.ai/docs/concepts/worlds.md) covers `world.json`; [Observing a simulator](https://www.rystic.ai/docs/concepts/observing.md) covers what to assert on.

## Every boot starts the same

1. The same command line boots the same state: `--scenario`, `--seed`, both, or neither.
2. State lives in memory. A restart discards everything since boot and boots that state again.
3. Requests run one at a time, so each one sees the state the one before it left.

## What reset does

`POST /_rystic/reset` answers `204`, and:

1. Wipes every register to empty. It does not load the boot `--scenario` again; `POST /_rystic/scenario` resets and loads a world in one call.
2. Restarts id sequences, so the first record after a reset gets the same id every time.
3. Sets the clock back to `initial_clock`.
4. Restarts the RNG from the last pinned seed.
5. Empties the egress log and the call log, and restarts their `seq` at 1.
6. Keeps a network profile you posted and the egress retention you set.

[What each plan boots](https://www.rystic.ai/docs/control-plane.md#what-each-plan-boots) lists what else a reset clears or keeps.

```bash
rystic pull lob-twin
PORT=$(rystic run lob-twin -d --name loop --port 0 --scenario design_studio --json | jq -r .data.port)
add() { curl -s -u test_x: localhost:$PORT/addresses -d name=Ada -d address_line1='185 BERRY ST' \
  -d address_city='SAN FRANCISCO' -d address_state=CA -d address_zip=94107 | jq -c '{id, date_created}'; }
add
# -> {"id":"adr_0000000000000001","date_created":"2026-03-01T00:00:00.001Z"}
curl -s -X POST localhost:$PORT/_rystic/reset
curl -s localhost:$PORT/_rystic/inspect
# -> {}
add
# -> {"id":"adr_0000000000000001","date_created":"2026-01-01T00:00:00.001Z"}
curl -s -X POST localhost:$PORT/_rystic/scenario -d '{"name":"design_studio"}'
add
# -> {"id":"adr_0000000000000001","date_created":"2026-03-01T00:00:00.001Z"}
```

## The clock

Every simulator keeps its own clock, and timestamps come from it.

1. **Where it starts.** A world sets its own instant: `design_studio` starts at `2026-03-01T00:00:00Z`. An empty boot starts at `2026-01-01T00:00:00Z`, except on S3, Clerk and Slack, which start at the wall time the process started. `GET /_rystic/version` shows the empty-boot instant as `initial_clock`.
2. **How it moves.** Each request that stamps a time moves it one millisecond. It never follows wall time unless you pace it ([below](#pacing)): two writes seconds apart still read `.001Z` and `.002Z`.
3. **Set it.** `POST /_rystic/clock` with `{"time":"<RFC3339>"}` sets it; `{"advance_seconds":N}` moves it forward. A world document's `clock` sets it too. Moving it past a loaded world's events fires them.
4. **Pin the start.** `rystic run --clock <RFC3339>` (`RYSTIC_CLOCK`) sets `initial_clock`, so an empty boot and every reset start there. Use it on S3, Clerk and Slack to make two processes agree.
5. **After a reset** it reads `initial_clock`, not the world's instant. Load the world again to get its clock back.

```bash
curl -s -X POST localhost:$PORT/_rystic/reset
curl -s localhost:$PORT/_rystic/version | jq .initial_clock
# -> "2026-01-01T00:00:00Z"
curl -s -X POST localhost:$PORT/_rystic/clock -d '{"time":"2026-06-01T09:00:00Z"}'
add
# -> {"id":"adr_0000000000000001","date_created":"2026-06-01T09:00:00.001Z"}
```

## The RNG

1. Every boot seeds the random stream with `1`.
2. `POST /_rystic/seed-rng` with `{"seed":N}` pins another; so do `rystic run --seed-rng N` and a world document's `rng_seed`. Every reset restarts the stream from the last pinned seed.
3. Ids are sequences, not random draws: the seed does not change them.
4. [Network profiles](https://www.rystic.ai/docs/control-plane.md#network-profiles-and-fault-injection) draw from it: the same seed and profile refuse the same requests in the same order.

## Pacing

The clock is manual by default: while your code is idle, nothing moves and no timeline event fires.

1. `RYSTIC_PACE=<speed>` moves the clock `speed` simulated seconds per wall second, firing events as they come due. `rystic run --speed <speed>` sets it.
2. `rystic run` paces at `1` on its own for an `--inject` schedule or a `--seed` world with events. `--speed 0` keeps the clock manual.
3. A paced clock follows wall time, so timestamps depend on when requests arrive.

```bash
rystic run lob-twin -d --name paced --port 0 --scenario design_studio --speed 3600
# one simulated hour per second: the world's hourly events fire as they come due
```

[Timelines](https://www.rystic.ai/docs/control-plane.md#timelines) covers scheduling events.

## What is and isn't deterministic

From the same boot or reset, with the same requests in the same order, these repeat byte for byte:

1. Ids, numbers and sequences.
2. Timestamps, on a manual clock.
3. The egress log: its events, their order and their `seq`.
4. Network-profile rejections, for the same seed and profile.

These do not:

1. **Concurrent requests.** They run one at a time in the order they arrive, so which one gets which id changes run to run. Send them in a fixed order.
2. **A paced clock.** It follows wall time.
3. **An empty boot on S3, Clerk or Slack.** Its clock starts at the wall time the process started. Within one process every reset returns to that instant; across processes, pass `--clock`.
4. **Kalshi's recorded tape.** `btc15m_tape` plays on the wall clock, so what your code meets depends on when it acts ([Kalshi → Determinism & reset](https://www.rystic.ai/docs/simulators/kalshi.md#determinism--reset)).
5. **Restarts.** They discard everything since boot.

Done with the example: `rystic stop loop` and `rystic stop paced`.

---

Source: https://www.rystic.ai/docs/concepts/reset-and-determinism · Markdown: https://www.rystic.ai/docs/concepts/reset-and-determinism.md
