Migration speed

330 MB / 1M rows moved end-to-end in 6.9 seconds (~48 MB/s) with the default engine and default flags — including preflight, copy, verification, and exact row-count matching.

The run

Phase Result
--plan-only (preflight + planning, zero target writes) 2.1 s
Real migration (--yes --force, copy + verify) 6.9 s
Throughput (dataset bytes / wall clock) ~47.9 MB/s
Engine (recorded in the report) orchestrated (pg_dump/pg_restore)
Copy verified yes
Row counts matched exactly yes (400k + 400k + 200k)

The sandbox carries deliberately broken settings (small shared_buffers, TLS off, superuser roles), so the preflight gate refused the first run — that refusal is recorded in the snapshot, and the measured run proceeded with --force, warnings attached to the report. The gate working is part of the evidence.

How to read this number

  • What it measures: the pipeline a real cutover uses — plan, copy, verify — at a scale where the copy dominates. If pgdba added 10 s of overhead, you would see it here; you don’t.
  • What it does not measure: network transfer (both databases are on one Docker instance), production I/O contention, or pgcopydb’s parallel throughput. Cross-host runs will differ.
  • The gate cost is ~2 s: preflight + planning + report, before any byte moves. That is what --plan-only gives you on every real migration.

Warning

Same instance, page-cache-friendly, Apple Silicon. Treat this as proof the pipeline is fast and honest at this scale — not as a production SLA. For prod numbers, run the same script against your own hosts.

Snapshot

docs/data/migration-evidence.json holds the full snapshot: date, pg versions, dataset bytes, per-run timings, engine, row counts, and the refusal record. It is committed — the number and its context travel together.

Reproduce it

uv run python devdb/bench_migration.py          # ~1M rows, writes the snapshot
uv run python devdb/bench_migration.py --rows 10000   # quick smoke

The driver seeds deterministic tables, times a plan-only dry-run and the real migration, parses the report, verifies row counts on the target, and drops everything it created.