Should You Run Databases on Kubernetes in 2026? 66% Do, RDS Costs 1.7x

Oct 31, 2026 · 13 min · Ajay Kumar

For most of my career my answer to "should we run the database on Kubernetes?" was a polite no. I did not trust volume attach and detach during a node drain, and the operators were young. In 2026 the honest answer to whether you should run databases on Kubernetes is "it depends, and here is exactly on what". This post covers the production evidence, what a database operator actually does, how the four main Postgres operators compare, why storage is still the hard part, and what RDS, Aurora and Cloud SQL cost next to plain EC2 nodes, from AWS's price list this week.

Can you run a production database on Kubernetes in 2026?

Yes, and plenty of people do. The Data on Kubernetes Community's 2025 report, based on a survey of 182 technology professionals, found databases were the most common data workload on Kubernetes for the fourth year running, at 66%, ahead of analytics (57%) and AI/ML (44%). The same report lists the pain: performance optimisation (46%), security and compliance (42%) and skills gaps (40%) are the top operational concerns, and storage I/O is the single biggest performance bottleneck at 24%.

Treat those numbers with scepticism: 54% of respondents work in technology companies, and people answering a Data on Kubernetes survey already run data on it. The practice is mainstream among practitioners; that does not mean it suits your team.

The operators look mature too. CloudNativePG was accepted into the CNCF Sandbox on 21 January 2025 and filed its incubation application in November 2025; the TOC assigned due diligence in July 2026, and a TOC vote opened on the issue on 30 October 2026. Its ADOPTERS.md lists 52 organisations running it in production, including IBM, Google Cloud, Microsoft Azure, GEICO Tech and Tesla. One entry, Brella, says it moved from Cloud SQL to CloudNativePG and that the change "saves us money and gives us more control". The question is no longer whether it can be done, but whether your team wants to own the runbook RDS runs for you today.

What a Postgres operator does that a StatefulSet can't

A StatefulSet gives each pod a stable name and its own PersistentVolumeClaim, and since Kubernetes 1.32 the PVC retention policy that decides whether those claims are deleted with the set is GA. That is useful plumbing, but it does not know which pod is the primary, cannot promote a replica, takes no backups, and updates pods in ordinal order rather than replicas first. The CloudNativePG docs explain why it skips StatefulSets entirely: it manages Pods and PVCs directly so it can resize volumes, treat the primary differently from replicas, and keep PGDATA and WAL volumes coherent.

An operator is a runbook compiled into a controller. You declare the end state and it handles bootstrap, streaming replication, failover, rolling updates, backups and restores. With CloudNativePG, a three-instance cluster with continuous backup to S3 is this much YAML:

# CloudNativePG 1.30.1, Barman Cloud plugin 0.15.1, PostgreSQL 18.6
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: pg-main
spec:
  instances: 3                     # one primary, two streaming replicas
  imageName: ghcr.io/cloudnative-pg/postgresql:18.6-minimal-trixie
  primaryUpdateMethod: switchover  # roll replicas, then promote one
  storage:
    size: 50Gi                     # one PVC per instance, no StatefulSet
  plugins:
    - name: barman-cloud.cloudnative-pg.io
      isWALArchiver: true          # WAL and base backups go to an ObjectStore
      parameters:
        barmanObjectName: pg-main-s3

The YAML is the easy part. The 1.30.1 release of 23 September 2026 fixes a failover that "could stall forever or get silently reverted", an old primary that was never demoted when PostgreSQL stopped responding, and a sort bug that could have promoted the wrong standby. 1.30.0 added a Kubernetes Lease that the instance manager must hold before acting as primary. That is a healthy project fixing hard distributed-systems bugs in public, and exactly the class of bug a managed service fixes without you reading a changelog.

CloudNativePG vs Zalando vs Crunchy PGO vs Percona: which Postgres operator?

Four operators cover most production Postgres on Kubernetes. Three of them wrap Patroni for leader election; CloudNativePG uses its own instance manager and the Kubernetes API.

Operator Latest release License HA mechanism Backup tool Notable 2025-2026 change
CloudNativePG 1.30.1, 23 Sep 2026 Apache-2.0, CNCF Sandbox Own instance manager, primary Lease Barman Cloud plugin 0.15.1, volume snapshots 1.31 is the last release with in-tree Barman Cloud; removed in 1.32.0
Zalando postgres-operator 2.0.3, 2 Oct 2026 MIT Patroni via Spilo WAL-E by default, WAL-G 2.0 dropped Postgres 13, made scram-sha-256 the default
Crunchy PGO 6.0.3, Aug 2026 Apache-2.0 Patroni pgBackRest v1 PostgresCluster API; Crunchy bought by Snowflake in 2025
Percona Operator for PostgreSQL 3.1.0, 9 Sep 2026 Apache-2.0, based on PGO Patroni pgBackRest 3.0 moved CRDs to its own API group; 3.1 adds pg_tde encryption

GitHub stars on 24 October 2026 were 9,482 for CloudNativePG, 5,258 for Zalando, 4,456 for Crunchy and 385 for Percona: a popularity proxy, not a quality metric.

Some details matter more than the table. CloudNativePG's 1.30.0 notes said native Barman Cloud support would go in 1.31.0; on 21 October the supported releases page moved that to 1.32.0, so .spec.backup.barmanObjectStore users must migrate before 1.32. Zalando's 2.0 release switched kubernetes_use_configmaps on by default "because endpoints will disappear", a reminder that operators break when Kubernetes APIs change underneath them. Snowflake bought Crunchy Data in June 2025, less than three weeks after Databricks bought Neon, so the PGO roadmap now belongs to a data warehouse company. Percona's 3.0.0 renamed its Crunchy-derived CRDs to upstream.pgv2.percona.com so the two can coexist and PGO users can migrate, and 3.1.0 added transparent data encryption with pg_tde and HashiCorp Vault.

My default for a new platform is CloudNativePG: the most momentum, no Patroni layer to reason about, and vendor-neutral governance. If your team already runs Patroni well, Zalando or Percona are reasonable. The companion CloudNativePG setup guide walks through it end to end.

Storage: network volumes, local NVMe and the I/O bottleneck

Storage is where databases on Kubernetes still hurt, and the survey agrees. The CloudNativePG storage docs make the trade explicit: network storage (EBS, Persistent Disk, Ceph) brings the latency and contention you would see on VMs, often worse on a shared backend, while local storage enables a shared-nothing design better suited to high-transaction and very large databases.

Three things catch teams out.

First, double replication. Postgres already keeps a full copy on every replica, so a storage layer that also keeps three copies (Ceph, Longhorn) multiplies writes; the docs recommend one storage replica, with no disk holding blocks from two instances of the same cluster.

Second, local NVMe in the cloud is ephemeral. AWS states that instance store data does not survive a stop, hibernate or terminate. A three-instance cluster survives losing a node because the operator re-clones the replica, but every node rotation becomes a full copy of the database over the network. If you run Karpenter with consolidation, set disruption budgets or the karpenter.sh/do-not-disrupt annotation on database pods; my autoscaling explainer covers how consolidation decides what to evict.

Third, tuning network volumes used to mean recreating them. VolumeAttributesClass went GA in Kubernetes 1.34, so on CSI drivers that support it you can change provisioned IOPS and throughput on a live PVC. Whatever you choose, benchmark it first: the docs recommend fio for the disk and pgbench for the database, and kubectl cnpg fio and kubectl cnpg pgbench launch both inside the cluster.

Memory sizing matters as much as disk. Set memory requests equal to memory limits for database pods, so a pod never uses more than it asked for and sits at the back of the kubelet's eviction queue under node pressure; my post on requests and limits explains the QoS classes.

What does Postgres on Kubernetes cost compared with RDS, Aurora and Cloud SQL?

I pulled on-demand prices from AWS's public RDS price list for us-east-1 (the file I checked was published 29 October 2026), the EC2 on-demand price table, EKS pricing and the Cloud SQL pricing page. Graviton nodes with 4 vCPU and 16 GiB unless noted; 730 hours a month.

Option Shape $/hour $/month Premium over EC2
RDS Multi-AZ DB cluster (writer + 2 readable standbys) 3x db.m8gd.xlarge 1.1856 865 1.71x
RDS Multi-AZ instance (1 non-readable standby) 2x db.m8gd.xlarge 0.7904 577 1.71x
RDS Single-AZ 1x db.m8g.xlarge 0.336 245 1.87x vs m8g.xlarge
Aurora PostgreSQL Standard, 3 instances 3x db.r8g.xlarge (32 GiB) 1.656 1,209 2.34x vs r8g.xlarge
Cloud SQL Enterprise HA, us-central1 4 vCPU, 16 GiB, primary + standby 0.5544 405 not compared
EC2 nodes for an operator 3x m8gd.xlarge (237 GB local NVMe each) 0.6919 505 baseline
EC2 nodes for an operator 3x r8g.xlarge (32 GiB) 0.7069 516 baseline
Monthly on-demand compute for HA Postgres with 4 vCPU nodes (USD, 730 hours) managed service EC2 nodes, operator Aurora PostgreSQL, 3x r8g.xlarge $1,209 RDS Multi-AZ cluster, 3x m8gd.xl $865 RDS Multi-AZ instance, 2x m8gd.xl $577 Cloud SQL HA, 2x 4 vCPU/16 GiB $405 EC2 for CNPG, 3x r8g.xlarge $516 EC2 for CNPG, 3x m8gd.xlarge $505 $0$400$800$1,200 AWS us-east-1 price list, 20 Oct 2026; Cloud SQL Enterprise, us-central1; r8g rows have 32 GiB nodes Excludes storage, backups, I/O and people. An EKS cluster adds $73 a month, shared by every workload.
Monthly on-demand compute from the AWS Price List API (RDS, us-east-1, published 20 October 2026), the EC2 on-demand table and Cloud SQL list prices. Scale: 0.36 units per dollar.

On compute, RDS charges about 1.7x the EC2 price for the same Graviton instance, and Aurora about 2.3x. Storage widens the gap: RDS gp3 is $0.115 per GB-month per copy ($0.345 for a three-node DB cluster), Aurora Standard $0.10 plus $0.20 per million I/O requests, EBS gp3 $0.08. The EKS control plane adds $73 a month, shared by everything in the cluster.

The number that surprised me is Extended Support. The price list charges $0.10 per vCPU-hour for RDS Extended Support on PostgreSQL 13 and older in years one and two, and $0.20 in year three. On a 4-vCPU instance that is $0.40 an hour, more than the $0.336 the db.m8g.xlarge itself costs. PostgreSQL 14 reaches community end of life on 12 November 2026, and AWS's release calendar moves RDS 14 to Extended Support pricing on 1 March 2027. On Kubernetes an old major version costs nothing extra, and nobody patches it.

Now the honest part. The gap between RDS and EC2 on a three-node cluster is about $360 a month: real money across fifty clusters, noise at one, where a single afternoon spent debugging a stuck failover costs more. The cost argument for databases on Kubernetes is a fleet argument.

What you take on when you leave RDS

Running Postgres yourself means owning a list that RDS currently hides:

  • Operator upgrades on a schedule. CloudNativePG ships a new minor every two to three months and supports each until three months after the next; 1.29 reached end of life on 29 September 2026, and 1.31.0 is now expected around December 2026.
  • Security advisories. 1.30.0 fixed CVE-2026-55769, where a database owner could plant operators in public that the operator's superuser probes then ran, a chain that could end in code execution in the pod. It also authenticated instance-manager endpoints that relied on network isolation, without a backport; older releases should restrict the status port with a NetworkPolicy.
  • Restores, not just backups. Nobody tests your restore path unless you schedule it, and point-in-time recovery does not cross major versions.
  • Major upgrades. CloudNativePG's in-place pg_upgrade takes the whole cluster offline and re-clones replicas afterwards. PostgreSQL 19 is planned for GA on 19 November 2026, and CloudNativePG 1.30 supports 14 to 18, so the operator has to catch up before you can.
  • On-call. Someone has to understand replication lag, WAL archiving and fencing well enough to act at night.

This is where platform discipline earns its keep in the AI era. Vendors are betting agents and AI apps will create far more databases: 77% of DoK respondents call vector databases critical infrastructure, and two Postgres companies were bought by data platforms within three weeks. An operator turns "create a database" into a YAML file, which is wonderful until an agent with kubectl access creates forty of them and nobody wired up backups. GitOps, admission policies and a backup alert per cluster are the boring controls that keep that safe.

When a managed database is still the right answer

Pick RDS, Aurora or Cloud SQL when:

  • you run one to five databases and nobody on the team wants Postgres on-call;
  • you need provider features such as Aurora fast clones, Global Database or IAM database authentication;
  • auditors want vendor-attested backup and patching evidence rather than your runbook;
  • your Kubernetes clusters are themselves young or frequently rebuilt.

Kubernetes wins when:

  • you run many small databases (per tenant, per preview environment) declared in Git next to the apps, a silo pattern my multi-tenant SaaS explainer compares with shared pools;
  • you already operate Kubernetes well, with GitOps, monitoring and people who read release notes;
  • you want local NVMe performance that managed services price as a premium tier;
  • you need the same database stack on two clouds or on-premises.

If the real decision is rent or own, the self-hosting vs SaaS post has the wider framework.

FAQ

Is it safe to run PostgreSQL on Kubernetes in production?

Yes, with a mature operator, three instances across zones, continuous WAL archiving to object storage and scheduled restore tests. Databases were the top Kubernetes data workload in the 2025 DoK survey at 66%. The risk is less Kubernetes itself than whether your team will run upgrades, read advisories and practise restores.

Does CloudNativePG use StatefulSets?

No. CloudNativePG manages Pods and PersistentVolumeClaims directly, so it can resize volumes, update replicas before the primary and keep data and WAL volumes coherent. Zalando's operator, by contrast, uses StatefulSets with Patroni.

Is running Postgres on Kubernetes cheaper than RDS?

On compute, yes: RDS charges about 1.7x the EC2 on-demand price for the same Graviton instance in us-east-1, and Aurora about 2.3x. On one three-node cluster the saving is a few hundred dollars a month, which one serious incident can erase; the case gets strong at fleet scale.

Which Kubernetes Postgres operator should I choose in 2026?

CloudNativePG for new platforms: Apache-2.0, CNCF Sandbox with incubation under review, no Patroni and the largest community. Choose Zalando, Crunchy PGO or Percona if you already depend on Patroni or pgBackRest, or need Percona's pg_tde encryption.

This quarter I would do three things. If you are on RDS PostgreSQL 14, schedule the major upgrade before the 1 March 2027 Extended Support start, because that bill is avoidable. If you already run CloudNativePG, get to 1.30.1 for the security fixes and move every cluster to the Barman Cloud plugin now, rather than in a hurry when 1.32 removes the in-tree code. And if you are deciding fresh, run one non-critical database on Kubernetes for a quarter, including a timed restore drill and an operator upgrade, before you move anything that pages you.

Related: Is Kubernetes Still Worth It in 2026? v1.37, 82% in Production, Real Costs, Vector Databases in 2026: Do You Need One, or Is pgvector Enough? and Self-Hosting vs SaaS in 2026: 37signals Saved $2M a Year. Should You?.

I'm Ajay Kumar — I build and operate PandaStack, an open-source Firecracker microVM cloud for AI agents, and write about the infrastructure and tooling around it.

Need this kind of infrastructure work? See what I do or email hello@ajayk.sh.


Related