Run Your Own Managed Postgres with Oxide, Kubernetes, and CloudNativePG

What managed Postgres is, and why it took over

Postgres has become the default database for a lot of modern software teams. In the 2025 Stack Overflow Developer Survey, it was used by 55.6% of professional developers, making it the most used and admired database in the survey. For a team starting a new application today, Postgres is often the obvious relational database choice.

But most teams, especially in Cloud, aren’t running Postgres themselves. They’re using a managed database service such as Amazon RDS, Aurora, Google Cloud SQL, or Azure Database for PostgreSQL. The idea behind managed database is pretty simple. You get a connection string, and the cloud provider takes care of most of the operational work including automatic failover, continuous backups, point-in-time recovery, and redundancy. The goal is for the application team to think about queries, schemas, and performance instead of keeping a database cluster alive.

The market has followed that shift with the cloud database and DBaaS market worth roughly $23.45 billion in 2025 and is expected to grow at close to 16% annually, reaching more than $91 billion by 2034. AI is adding another reason for that growth. Agents, RAG systems, and feature stores all need somewhere to keep application state, metadata, and increasingly vector data through extensions such as pgvector.More applications now depend on the database for more of their core functionality, which makes having a reliable managed database even more valuable.

The pain of managed Postgres in the public cloud

The managed tier is convenient, which comes with a hefty price tag.

Cost is the first problem. A managed database bills for compute, storage, provisioned IOPS, backup storage, egress and so on. Turn on Multi-AZ for high availability and the compute roughly doubles, for a standby you never touch. Scale managed databases to production instances across a fleet and the number reaches six figures a year fast, and also offers a perfect lock in environment with every gigabyte you store raises the cost of leaving later.

Sovereignty is the second challenge, with managed databases. The EU Cloud Sovereignty Framework landed in October 2025 with explicit penalties against US legislation like the CLOUD Act. The EU Data Act took effect in September 2025, adding mandatory data portability rules, including two-month termination windows and 30-day export deadlines for cloud providers. For regulated businesses serving European or UK customers, storing data in a US hyperscaler region is now an active compliance problem.

Organizations are dealing with two dilemmas.

  • How do we run managed Postgres as cost-effectively as possible?
  • How do we satisfy residency requirements?

Answer is quite simple: Stop renting the managed tier and start owning it.

Oxide is the substrate

Enterprises want the managed database experience without the hyperscaler bill or the residency risk, and without rewriting application code. Oxide provides the substrate: compute, storage, network, and observability in an API-driven approach. A managed Postgres tier sits on top of that, the same way object storage, Kafka, or Kubernetes would.

For managed Postgres workloads, these Oxide primitives come into play:

  • Cloud API: Provision instances, disks, VPCs, firewall rules through one consistent interface.
  • Anti-affinity groups: Ensure distributed services are not co-located on the same compute sled, preventing a single sled failure into a service failure.
  • Floating IPs: Provide a stable customer-facing object storage endpoint that does not change when the underlying infrastructure scales.
  • Flexible disk types: Support replication at the application layer or infrastructure layer, depending on architecture needs.

Postgres needs an orchestration layer to deliver the managed behavior which is possible with Kubernetes on those primitives and lets an operator drive the database lifecycle.

Why CloudNativePG first?

The primitives above are a solid foundation to run a managed Postgres tier on Oxide. For this build, we chose CloudNativePG as the first operator to evaluate, primarily because it’s a mature, CNCF project purpose-built for running Postgres on Kubernetes. It handles failover, streaming replication, backups, point-in-time recovery, and rolling upgrades declaratively, so you describe the cluster you want and the operator maintains it.

CloudNativePG runs in production at Tesla, IBM, and Ericsson, at GEICO across cloud and on-premises, and Mirakl runs 450 Postgres clusters and 31 TB of data on it. Both Google Cloud and Microsoft Azure ship and support it. Brella moved off Google’s managed Cloud SQL onto CloudNativePG, cut their bill, and in their words didn’t lose any functionality.

Other Postgres operators could run on the same Oxide foundation. The infrastructure underneath is intentionally operator agnostic.

Architecture

This architecture runs a distributed Postgres 17 cluster on Oxide, managed by CloudNativePG on a Kubernetes cluster, with the following components:

  • A 3-instance Postgres cluster: one primary and two hot standbys, each pinned to a different Oxide sled by anti-affinity. Async streaming replication keeps the standbys current.
  • A Kubernetes cluster (RKE2, three control planes and three workers) that hosts the operator and the database pods.
  • A PgBouncer connection pooler that holds client connections steady through a failover.
  • Continuous WAL archive and daily base backups to a MinIO S3 Object Storage
  • A Floating IP, allocated through the Kubernetes cloud controller manager (CCM), that gives applications a single, stable read-write endpoint.

Everything stays inside a single security boundary within the silo.

Here is the process flow:

Application connects to the Floating IP endpoint –> PgBouncer pooler routes the connection to the current primary –> Postgres commits the write to local NVMe and streams it to both standbys –> every WAL segment ships continuously to object storage for backup and point-in-time recovery.

When the primary dies, CloudNativePG promotes the most current standby, repoints the endpoint, and rebuilds the old primary as a standby without human in the loop.

Reference architecture diagram

Reference Architecture

Architecture Decisions

Let’s discuss the architecture decisions we made for this setup.

Local NVMe for data and WAL, distributed disks for boot

Commit latency in Postgres is driven by how fast the WAL logs reaches durable storage. Putting WAL on Oxide’s local NVMe keeps that write on the sled, off the network path. Data files sit on local NVMe too, on a separate volume so data I/O never competes with WAL fsync. Boot disks stay on distributed storage, where the 3x Crucible replication buys resilience that matters for the OS image and stays out of the database hot path.

Primary plus two standbys, async replication

With a single standby, a primary failure forces a choice between accepting data loss and refusing to fail over until the WAL gap reconciles. With two, the operator promotes the most up-to-date replica and rebuilds the other from the new primary. Async replication keeps commit latency low and accepts that a primary crash can lose the last few unshipped WAL bytes, typically milliseconds of writes. Workloads that require zero data loss switch to synchronous replication and accept the latency cost.

Anti-affinity across sleds

Oxide’s anti-affinity group places each Postgres instance on a different physical sled. One sled failure takes at most one replica, which the cluster tolerates without interruption. The safety is transitive: the Oxide group spreads the Kubernetes workers across sleds, one worker maps to one sled, and Kubernetes pod anti-affinity spreads the Postgres pods across workers. This results in real hardware separation, not just a software zone label.

Backups to MinIO, a separate failure domain

Backups colocated with the primary data are not backups. The WAL archive and base backups land on a Object Storage. A scoped service account limits CloudNativePG to its own backup bucket.

A pooler and a Floating IP for a stable endpoint

Applications connect to one Floating IP, fronted by a PgBouncer pooler in transaction mode. When CloudNativePG promotes a new primary, the endpoint follows it automatically and the pooler holds in-flight connections rather than dropping them. The application reconnects and keeps writing, with no config change and no DNS TTL wait.

The operator over hand-rolled scripts

CloudNativePG does Failover, replication, backup, PITR, and rolling upgrades declaratively and is battle-tested across thousands of clusters.

GitHub Repository

The full build is open-sourced at github. It’s a self-contained lab guide to build the stack in phases:

  • Provision the Oxide infrastructure with the oxide CLI: project, VPC, subnet, firewall rules, and instances.
  • Stand up the Kubernetes cluster through Rancher with the Oxide node driver.
  • Prepare the backup bucket and scoped credentials on object storage, using the companion MinIO on Oxide build or any S3-compatible endpoint.
  • Install the CloudNativePG operator and the Barman Cloud Plugin, set up local-path storage on the workers, and apply the 3-node Postgres cluster.
  • Wire continuous WAL archiving and a daily base backup schedule to S3.

Then it proves the cluster actually recovers, with three drills: kill the primary and watch CloudNativePG promote a standby, drop a table and recover it to the second with point-in-time recovery, and rebuild the entire cluster from S3 after deleting it.

This isn’t a single terraform apply today. Infrastructure comes up through the Oxide CLI and the Kubernetes layer through Rancher and Helm, so the build is a short, documented sequence rather than one button. For one button build, wrap the infrastructure in the Oxide Terraform provider and the operator and cluster in the Helm and Kubernetes providers, as two staged run behind a single wrapper.

Watch the build

Demo: Build Your Managed Database

Conclusion

For years the managed database was limited to hyperscalers. What held organizations in place was the operational layer around it, and the platform that layer needed underneath. Postgres is Postgres, irrespective of platform. With Oxide as the substrate, the hardware and software are co-designed into a simple API-driven experience, CloudNativePG runs the database lifecycle on top, and the data, the backups, and the recovery rope all stay in a building you control.

The Cloud Computer is the platform. The database is yours.