DevOps · CNCF daily

CloudNativePG: Kubernetes-Native High Availability for PostgreSQL

CNCF Sandbox. A Kubernetes operator that runs PostgreSQL clusters with automated failover, rolling updates, backups to object storage and point-in-time recovery, without external HA tools.

6 min read

CNCF Sandbox

  • CloudNativePG
  • PostgreSQL
  • Kubernetes
  • Barman Cloud
  • PgBouncer
CNCF project page

CloudNativePG is a Kubernetes operator that manages the full lifecycle of PostgreSQL clusters: provisioning, replication, failover, rolling updates, backups and recovery. It addresses the long-standing difficulty of running a stateful, primary-standby database on Kubernetes, which previously relied on external high-availability tools such as Patroni, repmgr or Stolon layered onto StatefulSets. EDB built the operator internally as Cloud Native PostgreSQL and released it in May 2022 as an openly governed open source project under the name CloudNativePG. It was accepted into the CNCF at the Sandbox level on January 21, 2025.

CNCF daily · Sprint 2, day 2 · Database

At a glance

Category Database
CNCF status Sandbox. Accepted January 21, 2025
Written in Go
License Apache 2.0
Scope Vanilla PostgreSQL on vanilla Kubernetes; forks and other databases are out of scope
Key resources Cluster, Pooler, Backup, ScheduledBackup, Database, Publication, Subscription, ImageCatalog
Recent milestone 1.28 (December 9, 2025): quorum-based failover stable, PostgreSQL 18 default

Architecture

flowchart TB
  OP[CloudNativePG operator<br/>reconciles Cluster resources] --> P1[Pod 1<br/>primary]
  OP --> P2[Pod 2<br/>standby]
  OP --> P3[Pod 3<br/>standby]
  P1 -- streaming replication --> P2
  P1 -- streaming replication --> P3
  P1 --> V1[PVC]
  P2 --> V2[PVC]
  P3 --> V3[PVC]
  RW[Service rw] --> P1
  RO[Service ro] --> P2
  RO --> P3
  APP[Applications] --> PGB[Pooler<br/>PgBouncer]
  PGB --> RW
  P1 -- WAL archive and base backups --> OBJ[Object storage<br/>via Barman Cloud plugin]
Component Responsibility
Operator Watches Cluster resources and manages pods and persistent volume claims directly, without StatefulSets, so it controls the order of failover, switchover and upgrades.
Instance manager Runs as the entrypoint in every PostgreSQL pod, starts and supervises Postgres, reports status and executes operator decisions such as promotion.
Services -rw always points to the primary, -ro to standbys and -r to any instance; failover updates endpoints automatically.
Pooler Optional PgBouncer deployment managed by the operator for connection pooling.
Barman Cloud plugin Continuous WAL archiving and base backups to S3, Azure Blob Storage or Google Cloud Storage, enabling point-in-time recovery.
CNPG-I The plugin interface that lets backup and other capabilities ship independently of the operator.

Design principle. The Kubernetes API is the source of truth for cluster state. Instead of an external consensus system deciding who is primary, the operator and instance managers use Kubernetes resources and status, which keeps the architecture small and observable with standard Kubernetes tools.

Production reference design

A typical deployment on EKS, GKE, AKS or on-premises uses three instances across availability zones, backups to object storage and a pooler in front.

  1. Install the operator with the official Helm chart:
    helm repo add cnpg https://cloudnative-pg.github.io/charts
    helm upgrade --install cnpg cnpg/cloudnative-pg \
      --namespace cnpg-system --create-namespace
    Install cert-manager and the Barman Cloud plugin as well; backups are moving from the operator’s in-tree support to the plugin, and the in-tree implementation is scheduled for removal in a future minor release.
  2. Define the backup target as an ObjectStore, using workload identity (IRSA on EKS) rather than static keys.
  3. Create the cluster, spread across zones, with synchronous replication for zero data loss on failover:
    apiVersion: barmancloud.cnpg.io/v1
    kind: ObjectStore
    metadata:
      name: s3-backups
    spec:
      retentionPolicy: "30d"
      configuration:
        destinationPath: s3://acme-pg-backups/shop
        s3Credentials:
          inheritFromIAMRole: true
        wal:
          compression: gzip
    ---
    apiVersion: postgresql.cnpg.io/v1
    kind: Cluster
    metadata:
      name: shop-db
    spec:
      instances: 3
      imageName: ghcr.io/cloudnative-pg/postgresql:18
      storage:
        size: 100Gi
        storageClass: gp3
      postgresql:
        parameters:
          shared_buffers: "2GB"
          max_connections: "300"
        synchronous:
          method: any
          number: 1
      affinity:
        topologyKey: topology.kubernetes.io/zone
      resources:
        requests: { cpu: "2", memory: 8Gi }
        limits: { memory: 8Gi }
      monitoring:
        enablePodMonitor: true
      plugins:
        - name: barman-cloud.cloudnative-pg.io
          isWALArchiver: true
          parameters:
            barmanObjectName: s3-backups
    ---
    apiVersion: postgresql.cnpg.io/v1
    kind: ScheduledBackup
    metadata:
      name: shop-db-nightly
    spec:
      schedule: "0 0 21 * * *"
      cluster:
        name: shop-db
      method: plugin
      pluginConfiguration:
        name: barman-cloud.cloudnative-pg.io
  4. Add a Pooler with PgBouncer in transaction mode for applications that open many short connections.
  5. Observe with the built-in Prometheus metrics, the community Grafana dashboard and the kubectl cnpg plugin (kubectl cnpg status shop-db).
  6. Rehearse recovery by bootstrapping a new cluster from the object store to a target time, and by running a planned switchover with kubectl cnpg promote.

Typical production uses are application databases for microservices, multi-tenant platforms providing PostgreSQL as a service on Kubernetes, and replica clusters in a second region for disaster recovery.

Operational considerations

  • Scaling: scale reads by adding instances and pointing read traffic at the -ro service; writes scale vertically. Use a Pooler before raising max_connections.
  • High availability: spread instances across zones, use synchronous replication where data loss is unacceptable, and protect pods with the PodDisruptionBudgets the operator creates. Quorum-based failover (stable since 1.28) reduces the risk of promoting a standby that missed committed transactions.
  • Security: TLS is enabled by default with operator-managed certificates; integrate cert-manager for your own CA. Store application credentials in the generated Secrets, rotate them, and restrict pg_hba rules.
  • Cost and sizing: storage performance drives database performance; prefer gp3 or premium SSD classes with provisioned IOPS for busy clusters, and separate WAL volumes for write-heavy workloads.
  • Common pitfalls: untested backups, missing WAL archiving (which blocks point-in-time recovery), node pools without spread across zones, and storage classes that cannot expand volumes. Plan the migration from in-tree Barman backups to the plugin before upgrading to the release that removes them.

Adoption

The project’s end-user page lists organisations including EDB, Tembo, ParadeDB, REWE International AG, Docaposte, Mirakl, Hitachi, the Rubin Observatory and pgEdge, and further adopters are recorded in the repository’s ADOPTERS file. EDB states that the project has dozens of adopters including all major cloud providers, and vendors such as Percona and pgEdge offer support or distributions based on it.

Alternatives

Solution Model Best suited to
Managed PostgreSQL (Amazon RDS and Aurora, Cloud SQL, Azure Database) Fully managed service outside Kubernetes Teams that prefer to buy database operations
Zalando Postgres Operator Operator using Patroni on StatefulSets Existing Patroni users
Crunchy Postgres for Kubernetes (PGO) Operator with Patroni and pgBackRest Organisations wanting Crunchy Data support
StackGres Operator with a web console and integrated stack Teams wanting a bundled UI
Self-managed VMs with Patroni Traditional HA outside Kubernetes Databases intentionally kept off the cluster

Strengths and limitations

Strengths Limitations
No external HA dependency; failover driven by Kubernetes state Running databases on Kubernetes still demands storage and operations expertise
Declarative backups, PITR and replica clusters Sandbox maturity; governance and APIs are still evolving
Strong defaults: TLS, metrics, PodDisruptionBudgets Backup architecture is in transition to the plugin model
Active release cadence and broad vendor support Vanilla PostgreSQL only; no support for forks
Plugin interface (CNPG-I) for extensions Write scaling remains vertical, as with any single-primary PostgreSQL

Recommendation

Trial for teams that already run stateful workloads on Kubernetes and want PostgreSQL alongside their applications, especially for on-premises or multi-cloud platforms. Start with a three-instance cluster across zones, the Barman Cloud plugin to object storage, and regular restore drills before moving critical data. Teams without Kubernetes storage experience, or with a managed database already in place, should keep the managed service.

References: CNCF project page · CloudNativePG documentation · Release notes for 1.28 · EDB announcement of the CNCF Sandbox milestone · End users · CloudNativePG on GitHub

Spotted something wrong or out of date?Suggest a correction. I review every suggestion before changing the page.