# Offline simulation
Source: https://sovaria.in/docs/offline-simulation

Run the SQL part of the access simulation on your own machine from a snapshot of the project — and see exactly what a migration changes — without a live project.

[Simulation](https://sovaria.in/docs/simulation) normally runs against your live project. Offline simulation takes a **snapshot** of the project's access surface — tables, columns, row-level security, row policies, your SQL functions, and every case of the simulation matrix with what your rules decided — and rebuilds it on a throwaway Postgres on your machine. Every SQL case then runs as each user type, with the same roles and session settings Sovaria uses, inside a transaction that is always rolled back.

1. **Record a snapshot** — In the console (Simulation › Simulate offline › Download snapshot) or from the CLI. Add sample rows if you have database read access; otherwise synthetic rows are made, a few owned by each user type.
```bash
sov simulate snapshot            # writes .sovaria/sim/snapshot.json
sov simulate snapshot --rows     # with sample rows (plan caps how many per table)
```
2. **Run it offline** — Uses Docker (postgres:16) by default, or a scratch database on a Postgres you give with --pg-url.
```bash
sov simulate offline
sov simulate offline -v          # every case
```
3. **Try a change before you make it** — With migrations the matrix runs before and after; every case whose outcome or visible rows changed is listed. --fail-on makes it a CI gate.
```bash
sov simulate offline -m migrations/2026_10_add_sharing.sql --fail-on change
```

Output:
```text
SQL cases 48: 31 allowed, 17 denied, 0 errors; 0 deviation(s); 12 need the live runtime
Migration migrations/2026_10_add_sharing.sql: applied
  CHANGED app:member sql:read todos: ALLOW (2 row(s)) → ALLOW (8 row(s))
  CHANGED __guest__ sql:read todos: ALLOW (0 row(s)) → ALLOW (8 row(s))
```

> **Warning:** Your rules' verdicts (Guard) are frozen at snapshot time; Postgres — grants, row policies, and the migration you pass — is evaluated locally. Storage, functions, realtime and documents need the live runtime: run [sov sim run](https://sovaria.in/docs/simulation) for those. Without `policies.read` a snapshot has no policy text, and the report says so.

Against a local Sovaria stack, `sov simulate local --profile <localhost profile>` runs the full simulation there instead of the cloud.

|  | Free | Pro | Ultra | Team | Enterprise |
|---|---|---|---|---|---|
| Project snapshots for offline simulation per month | 5 | 50 | 200 | 1,000 | 5,000 |
| Sample rows per table in a simulation snapshot | 100 | 1,000 | 5,000 | 10,000 | 50,000 |
