How to enable streaming replication in PostgreSQL running in kubernetes pods?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
PostgreSQL streaming replication keeps a standby server synchronized with a primary by continuously shipping and replaying WAL (Write-Ahead Log) records. Running this inside Kubernetes requires StatefulSets for stable pod identities, ConfigMaps for PostgreSQL configuration, and careful networking between primary and replica pods. For production use, consider an operator like CloudNativePG or Zalando's postgres-operator, but understanding the manual setup clarifies what the operators automate.
Prerequisites
Before starting, you need a running Kubernetes cluster with kubectl configured, a PostgreSQL Docker image (the official postgres:16 image works), and a basic understanding of StatefulSets and persistent volumes.
Step 1: Create a ConfigMap for PostgreSQL Settings
The primary server needs WAL-level settings that enable replication.
wal_level = replica enables streaming replication. max_wal_senders controls how many standby connections the primary accepts. The pg_hba.conf entry allows a replicator user to connect for replication from any pod in the cluster.
Step 2: Create a Secret for Replication Credentials
Step 3: Deploy the Primary with a StatefulSet
A headless service (clusterIP: None) gives each pod a stable DNS name like postgres-primary-0.postgres-primary.
Step 4: Create the Replication User
Connect to the primary pod and create the replication user:
Step 5: Deploy the Replica
The replica uses pg_basebackup to initialize from the primary, then streams WAL changes continuously.
The -R flag in pg_basebackup creates a standby.signal file and writes connection info to postgresql.auto.conf, so the replica automatically connects to the primary for streaming.
Step 6: Verify Replication
Common Pitfalls
- Forgetting to set
wal_level = replicaon the primary — without this, replicas cannot connect. - Not creating the replication user with the
REPLICATIONprivilege —pg_basebackupfails with permission denied. - Using a Deployment instead of a StatefulSet — Deployments do not provide stable network identities or persistent storage across restarts.
- Skipping the
pg_hba.confreplication entry — the primary rejects replication connections even with valid credentials. - Not monitoring replication lag — use
pg_stat_replicationon the primary to detect replicas falling behind.
Summary
- Use StatefulSets with headless services for stable pod DNS names.
- Configure
wal_level = replicaandpg_hba.confreplication entries on the primary. - Initialize replicas with
pg_basebackup -Rto auto-configure streaming connection. - Verify replication with
pg_stat_replicationon the primary andpg_is_in_recovery()on the replica. - For production, consider PostgreSQL operators (CloudNativePG, Zalando) that automate failover and backup management.
Related reading
- How to enforce MustRunAsNonRoot policy in K8S cluster in AKS
- How to ensure kubernetes cronjob does not restart on failure
- How to enter a pod as root?
- How to estimate Kubernetes Resources for a Pod
- How to establish a connection to DynamoDB using python using boto3
- How to export an existing dynamo table schema to json?
- How to ensure data consistency in Cassandra on different tables?
- How to establish a consistent hash ring with 300 million virtual nodes within 10 seconds with C++

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.