Skip to content

The sandbox

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

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.

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 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 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.
Navigation

Type to search…

↑↓ navigate↵ selectEsc close