Blog
DevOps10 min read
Zero-Downtime PostgreSQL Migrations on Kubernetes
B
BADJO Dibéa Koffi
Published on May 10, 2026
The Problem
You push a migration that adds a NOT NULL column to a table with 50 million rows. PostgreSQL acquires an ACCESS EXCLUSIVE lock. Every query blocks. Your API returns 504s for 3 minutes.
The Rules
- Never add a NOT NULL column without a default — PostgreSQL 11+ handles this without rewriting the table.
- Never drop a column in the same release that stops using it — deploy code that ignores the column first.
- Never rename a column — add new, migrate data, update code, drop old. Three releases.
- Always add indexes CONCURRENTLY —
CREATE INDEX CONCURRENTLYdoesn't lock the table. - Separate migration execution from application startup.
Flyway + Init Containers
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
initContainers:
- name: migrate
image: flyway/flyway:10
args: ["migrate"]
env:
- name: FLYWAY_URL
value: jdbc:postgresql://db:5432/myapp
containers:
- name: api
image: myapp:latestThe init container runs Flyway, waits for success, then the API starts.
Safe Migration Patterns
Adding a Column
-- Safe: nullable column, no lock
ALTER TABLE orders ADD COLUMN discount_code VARCHAR(50);
-- Safe in PG 11+: non-null with default
ALTER TABLE orders ADD COLUMN status VARCHAR(20) NOT NULL DEFAULT 'pending';Adding an Index
-- Safe: non-blocking
CREATE INDEX CONCURRENTLY idx_orders_status ON orders(status);Renaming a Column (3-Phase)
Phase 1: Add new column, backfill data Phase 2: Deploy code that writes to both, reads from new Phase 3: Drop old column in next release
The Checklist
- Does this migration acquire ACCESS EXCLUSIVE lock?
- Are all indexes created CONCURRENTLY?
- Is it backward compatible with currently deployed code?
- Tested on production-sized dataset?
- Is there a rollback migration?
Following these rules, we ran 200+ migrations on a 500GB database without downtime.
postgresqlkubernetesmigrationszero-downtime
Comments
Stay Updated
Get my latest articles delivered straight to your inbox.
Related Articles
DevOps11 min read
GitOps with ArgoCD: From Messy Pipelines to Declarative Deployments
How I replaced 2,000 lines of Jenkins scripts with a single ArgoCD ApplicationSet.
B
DevOps12 min read
Deploying LLM Inference on Kubernetes with vLLM
Serving a 13B model in production for under $200/month using smart scheduling and autoscaling.
B