# Case study: a 124k-row Supabase import
Source: https://sovaria.in/docs/import-case-study

A movie-ratings Supabase project — 124,003 rows, 610 users with passwords, 1,610 files and row-level security — moved with one command, timed and verified.

We imported a Supabase project shaped like GroupLens' MovieLens `ml-latest-small` (movies, links, 100,836 ratings, tags; foreign keys to `auth.users`; 4 row policies using `auth.uid()`; 2 buckets with 1,610 files) with `sov import supabase`, into a local Sovaria stack of the real engines, and checked every row.

| Phase | Time | Notes |
|---|---|---|
| Schema + row policies | 1.5 s | one migration |
| 610 users (bcrypt passwords kept) | 32 s | users sign in with their old passwords |
| 124,003 rows | 45 s | 189 requests; each batch of up to 200 statements is one transaction |
| 1,610 files (11.8 MiB) | 163 s | the slowest part today |
| **Total** | **4 min 2 s** | every table's row count and checksum match the source |

Writing this test changed the importer: data now loads in batches that are applied whole or not at all, so `--resume` continues exactly after the last committed batch (before, a failure in the middle of a batch could make a resume insert rows twice), and the data phase got 2.9× faster. Storage is copied 8 objects at a time (`--storage-concurrency`).

CLI:
```bash
sov import supabase --db-url "$SUPABASE_DB_URL" \
  --supabase-url https://<ref>.supabase.co --service-key "$SUPABASE_SERVICE_ROLE_KEY"
# big projects: one part at a time, resumable
sov import supabase --db-url "$SUPABASE_DB_URL" --only data --resume
```

> **Note:** The harness (Postgres, the real Atlas-Rel, Axis and Vault, the CLI) is reproducible with one command; numbers come from a laptop, so read them as relative. Firebase imports are not covered by this run yet.
