Cloud Migration
Moving 7 tenant databases off managed Postgres to self-hosted CloudNativePG
Migrating a multi-tenant SaaS platform from AWS RDS and Aurora Serverless v2 to self-managed PostgreSQL on Kubernetes with CloudNativePG — zero downtime for live tenants, and every managed instance retired.
- 7 + a 35-DB staging cluster
- Tenant clusters migrated
- Zero
- Source downtime
- 0 RDS / Aurora
- Managed instances left
// the challenge
A multi-tenant SaaS platform ran every tenant's database on AWS RDS and Aurora Serverless v2. Managed-Postgres cost and vendor lock-in were mounting, and the team wanted PostgreSQL on their own Kubernetes cluster — with self-managed HA and backups, no downtime for live tenants, and every RDS and Aurora instance gone by the end.
// our approach
- Deployed the CloudNativePG (CNPG 1.29) operator on a k3s cluster on Civo, with one Cluster resource per tenant running PostgreSQL 17.9 and PostGIS.
- Cloned each source with CNPG pg_basebackup physical streaming (bootstrapped via an SSH-tunneled import) — a healthy clone in roughly 5-10 minutes per cluster with zero source downtime.
- Set up continuous point-in-time recovery through the CNPG barman-cloud plugin v0.12.0: continuous gzip WAL archiving plus nightly and on-demand base backups to S3.
- Restructured databases into purpose-split namespaces via chained pg_basebackup, migrated secrets preserving their Kubernetes secret types with External Secrets Operator v0.10.3, and repointed 10 SSM parameters to in-cluster DNS behind Traefik ingress.
// the outcome
Seven tenant Postgres clusters (per-tenant storage from 20 to 300Gi, with four large tenants at 300Gi) plus a 35-database staging cluster now run on the platform's own Kubernetes with self-managed HA and PITR — and all AWS RDS and Aurora Serverless v2 instances were deleted after cutover, ending both the managed-Postgres bill and the lock-in.
Have a similar challenge?
Book a 15-minute call and we'll show you where we can help — no pitch, no obligation.
