Case Study ยท PostgreSQL ยท DevOps ยท Migration

120GB PostgreSQL Logical Replication Migration

Moving a live 120GB+ production PostgreSQL database from AWS EC2 to Hostinger VPS with zero downtime โ€” navigating OID mismatches, WAL slot exhaustion, partition table replica identity failures, and disk space constraints.

RoleDatabase & DevOps Engineer
Database Size120GB+ (PostgreSQL Database)
MethodLogical Replication
TypeZero-Downtime DB Migration

A production database that couldn't afford an hour of downtime โ€” let alone a weekend

PostgreSQL (120GB+) was on AWS EC2 serving a live production application. The client needed to migrate to another VPS to reduce costs โ€” but had no maintenance window. pg_dump and restore would require 4โ€“6 hours of downtime. Logical replication was the only viable path.

Risk: Logical replication has strict requirements around replica identity, partition tables, sequences, and OIDs โ€” any one of which can silently cause replication to lag or fail without obvious errors.

Six phases โ€” the wrong order would be catastrophic

1
Schema migration first (pg_dump schema-only)Tables, indexes, constraints, and sequences created on target before replication starts. Replication cannot create tables โ€” only replicate rows.
2
Set replica identity on all tablesSeveral legacy tables lacked primary keys. Applied REPLICA IDENTITY FULL to those โ€” with the trade-off of larger WAL records for updates and deletes.
3
Create publication on source, subscription on targetCREATE PUBLICATION rsb_pub FOR ALL TABLES on source. CREATE SUBSCRIPTION rsb_sub on target. PostgreSQL begins table sync then streams live WAL changes.
4
Monitor replication lag until near-zeroMonitored pg_stat_replication.write_lag. Waited for lag under 100ms across all tables before scheduling cutover.
5
Cutover โ€” app config switch + sequence syncMaintenance mode (30s) โ†’ sync all sequences manually (sequences don't replicate) โ†’ update DATABASE_URL โ†’ remove maintenance mode. Total downtime: 47 seconds.
6
Post-migration nightly backup pipelineShell script: pg_dump at 02:00 IST โ†’ gzip โ†’ rsync to backup server โ†’ SMTP alert on success or failure.

Four problems that nearly derailed the migration

120GB moved โ€” 47 seconds of customer-facing downtime

47s
Total application downtime
120GB+
Data migrated successfully
0
Rows lost during migration
60%
Infrastructure cost reduction

Result: 100% data integrity confirmed via row counts, sequence values, and spot-check queries against both databases post-cutover.


Back to all projects