Skip to main content

Rehearse a Postgres database transfer

Run a disposable source-to-destination logical dump/restore, verify grants and sequences, then practice writer freeze and cutover.

Share
Last updated on September 23, 2026
On this page

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:

  1. Creates owned source and empty destination databases with related seed data and a least-privilege transfer_app role
  2. Runs pg_dump / pg_restore (--no-owner --no-acl) with bounded lifetimes and refuses to promote a failed archive
  3. Verifies rows, relationships, sequences, and that the app role can read/write while DDL stays denied
  4. 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

bash
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 -- --container

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

Was this page helpful?

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex