---
title: "The sandbox"
description: "A sandbox is an isolated, disposable test database holding an organisation's schema and only the rows placed in it, never production data."
---

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

# The sandbox

A sandbox is an isolated, disposable test database holding your
organisation's schema, and only the rows you put in it. It never contains
production data. Closing a sandbox destroys its state, and idle sandboxes
are evicted after 30 minutes.

A sandbox proves your code works against this schema. It proves nothing
about whether a migration survives your real rows: that is a **rehearsal**,
which executes the migration against a disposable clone of the real
database and reports what Postgres did. See
[Change approval](/concepts/change-approval/).

## Two backends

| | In-memory | Postgres |
|---|---|---|
| Implementation | Pure-Go simulator, in process memory | Real Postgres process with a data directory |
| Boot | Sub-millisecond | A few seconds |
| SQL coverage | The subset the executor models | Postgres SQL |
| State ops (checkpoint, restore, fork, diff, seed, snapshot, inspect) | Native | Not supported |
| Determinism (fixed clock) | Honoured | Ignored; `now()` returns wall-time |

Pick **in-memory** for fast-iteration work: agent loops, "try N then
rewind," schema exploration, anywhere checkpoint and fork matter. Pick
**Postgres** when SQL fidelity matters: custom queries, triggers, plpgsql,
multi-table joins, complex `check` constraints. On the Postgres backend,
`vector(N)` columns become `BYTEA`, and HNSW indexes and hypertable
conversion are stripped from the DDL before it applies, so vector distance
operators fail at query time there.

## The state model (in-memory only)

The simulator uses copy-on-write row maps: a capture records pointers to
every table's current rows and marks them shared, and a later write clones
only the affected map. Checkpoint, restore, and fork therefore cost
`O(tables)` rather than `O(rows)`: row data is never copied at capture time.

Four primitives:

- **Checkpoint** — save the current state.
- **Restore** — rewind to a saved state; intermediate writes are dropped.
- **Fork** — clone the current state into N independent sandboxes, each
  with its own checkpoint history.
- **Diff** — added, removed, and modified row counts per table between two
  checkpoints.

Over HTTP, a state-op call against a Postgres-backed sandbox returns
`400` with `<feature> is in-memory only; boot a Sim sandbox to use it`.

## Supported SQL

The simulator's SQL grammar is supplied by `pg_query_go`, the Postgres
parser packaged for Go. Every Postgres syntactic construct parses; what
runs is what the in-memory executor models: single-table `SELECT` with
`WHERE` / `ORDER BY` / `LIMIT` / `OFFSET`, `INSERT` (with `RETURNING`),
`UPDATE` and `DELETE` (without `RETURNING`), `ON CONFLICT`, JSON arrow
extraction, vector distance operators, `= ANY($N)`, and the window-total
form `COUNT(*) OVER () AS alias`. Multi-table joins, CTEs, `GROUP BY`, and
every other window form are outside the surface.

[Sandbox SQL coverage](/reference/sandbox-sql/) is the complete list.

## Surfaces

The console's Sandbox page is the interactive surface: boot, seed, capture,
compare, restore, fork, all in the UI. The HTTP control plane at
`/api/sandbox/*` is the programmatic surface for scripts and agent loops;
both share one runtime. [`tide sandbox`](/reference/cli-tide/#tide-sandbox-bootshellspawn)
runs the same in-memory runtime locally. Booting requires the `developer`
or `admin` role, and each user holds up to 100 sandboxes at a time.

## What the sandbox does not model

- Production rows — every sandbox starts empty.
- Row-level tenant isolation: the in-memory backend does not enforce
  `partition by` policies, so it proves nothing about them.
- Migration safety against real data — rehearse the plan instead.

## Related

- [Use the sandbox](/guides/use-the-sandbox/) — walkthrough of the console flow.
- [Sandbox SQL coverage](/reference/sandbox-sql/) — the SQL the in-memory backend accepts.
- [Sandbox HTTP API](/reference/sandbox-api/) — programmatic surface.
- [Change approval](/concepts/change-approval/) — rehearsal, the real-data proof.

Source: https://docs.tryatlantis.dev/concepts/sandbox/index.mdx
