Move application data with a rehearsed logical transfer before you change writers or DNS. Bex Postgres connections preserve the TLS settings returned at provision time — do not weaken verification to make a migration command connect.
This page points at a downloadable two-database rehearsal you can run on local disposable Postgres 16. It is not a hosted migration service and must never target a customer database.
What the sample rehearses
The postgres-transfer example:
- Creates owned source and empty destination databases with related seed
data and a least-privilege
transfer_approle - Runs
pg_dump/pg_restore(--no-owner --no-acl) with bounded lifetimes and refuses to promote a failed archive - Verifies rows, relationships, sequences, and that the app role can read/write while DDL stays denied
- Shows why writes after an early dump are missing, stops the sample source writer, completes a final transfer, then enables destination writes once
Stopping the sample writer is not proof that every production writer is frozen. After destination writes begin, switching traffic back to the source leaves unreconciled data — decide how to reconcile before you need that path.
Run the rehearsal
curl -fsSLO https://bex.co/examples/postgres-transfer-latest.zip
curl -fsSLO https://bex.co/examples/postgres-transfer-latest.zip.sha256
shasum -a 256 -c postgres-transfer-latest.zip.sha256
unzip postgres-transfer-latest.zip
cd postgres-transfer
npm install
export SOURCE_DATABASE_URL=postgres://transfer_admin:transfer_admin@127.0.0.1:55434/transfer_source_fixture
export TARGET_DATABASE_URL=postgres://transfer_admin:transfer_admin@127.0.0.1:55434/transfer_dest_fixture
export APP_DATABASE_URL=postgres://transfer_app:transfer_app@127.0.0.1:55434/transfer_dest_fixture
npm run setup
npm run rehearse
npm run cutover
npm test
npm run teardown -- --containerRequires Docker (postgres:16-alpine). Client tools come from the container when
pg_dump / pg_restore are not on PATH. Archives stay under .rehearsal/ and
are not published with the downloadable tree.
How this maps to a real migration
Use the same sequence described in Migrate from Render
(and linked from Migrate from Heroku): empty
destination, compatible majors, explicit role/grant recreation after
--no-owner --no-acl, write freeze of all producers, final restore, then
enable destination writers once.