Running PostgreSQL on Kubernetes with CloudNativePG
A platform team that already runs Kubernetes and needs PostgreSQL with high availability and recoverable backups should treat the database as a Kubernetes workload. CloudNativePG is a Kubernetes operator that manages PostgreSQL clusters declaratively, so topology, storage, backup targets and upgrade settings are described as resources that the operator reconciles. The work is planned around failover, backup, recovery and upgrades. PostgreSQL does not detect a failed primary and notify a standby by itself, and automatic failover needs external tooling, so the operator's role in promotion decisions shapes the whole design. PostgreSQL is released under the PostgreSQL License, a liberal license similar to the BSD and MIT licenses, so the database carries no license fee. The cost sits in engineering time, infrastructure and support.
This page covers the integration method, the prerequisites, the build sequence, how PostgreSQL concepts map to Kubernetes objects, security, testing and the failure points that matter most. Start with two decisions. The first is whether the platform team will own the database lifecycle inside the cluster or keep it on virtual machines, which is a question of skills and operating model rather than a question of which product is better. The second is which Kubernetes distribution and version your organization will run, because the operator's supported Kubernetes versions must match your cluster. Confirm the compatibility matrix in the operator's documentation for your exact Kubernetes minor version, and check your storage class, volume snapshot support and node pool layout before any database object is created.
Ownership is split between the operator and the platform team, and the boundary should be written down. The operator manages primary and replica pods, promotion, service endpoints and PostgreSQL configuration. The platform team owns the storage classes, node placement, network policy, the object storage credentials used for WAL archiving and base backups, and the backup of etcd, which holds the cluster state. Kubernetes stores Secrets unencrypted in etcd by default, so encryption at rest must be configured before database passwords and backup credentials are written to the cluster. Restrict list and watch access to those Secrets with least-privilege RBAC, apply the Pod Security Standards to the namespace, and confirm how the operator manages the superuser and application credentials in your environment.
Testing should prove recovery, not only installation. Run planned failover by draining the node that holds the primary, then kill the primary pod without warning, and record how long clients take to reconnect and whether any acknowledged writes are missing. Restore a base backup and replay WAL to a point in time in a separate namespace, then check the restored data against a known transaction. The failure points to test deliberately are expired object storage credentials, WAL archiving that fails without an obvious alert, storage latency that slows replication, loss of the Kubernetes control plane that stops reconciliation, and an etcd restore that does not match the database backups. Ask the operator's maintainers and your storage vendor which metrics and events show each of these conditions.
When you request a quote, ask for the scope to list each of these items as a deliverable: the target Kubernetes and PostgreSQL versions, the storage and object store design, the security configuration, the failover and restore tests with their acceptance criteria, and the handover of runbooks to your team. One-time costs include design, build, migration and testing. Recurring costs include storage, object storage for backups, replica compute, monitoring, operator and PostgreSQL upgrades, and any retained support. Costs rise with the number of clusters, the size of the datasets, the recovery time you require and the number of environments that must be tested. Ask for the assumptions behind each estimate and for the work that stays with your own staff.
What a PostgreSQL on Kubernetes cluster needs before installation
Most problems in a first CloudNativePG installation trace back to decisions made before the operator is applied. The checks below cover the Kubernetes platform, the PostgreSQL version, the backup target and the people who will run the cluster, so each one can be confirmed in writing before installation starts.
Supported Kubernetes minor version
Kubernetes maintains only the three most recent minor releases. As of September 2026, these were 1.37 (end of life October 28, 2027), 1.36 (June 28, 2027) and 1.35 (February 28, 2027). Choose a minor version on that list and a distribution listed in the CNCF Certified Kubernetes program. Then confirm in the CloudNativePG documentation that the operator release supports that exact Kubernetes version, and plan the upgrade path before the first install.
Control plane and etcd backups
PostgreSQL pods depend on the Kubernetes API and etcd, so control plane design sets the impact of any failure. Kubernetes documentation describes a highly available control plane with at least three control plane nodes behind a TCP load balancer, and an etcd cluster with an odd number of members, five in production. Before installation, confirm who takes etcd snapshots with etcdctl, where they are stored, and who has tested a restore with etcdutl.
Storage classes and network paths
Each PostgreSQL instance needs a persistent volume from a storage class your team has tested for write latency, volume expansion and snapshot behavior. Confirm which storage class the operator will use, which access modes it needs and which node pools the volumes can attach to. Also map the network paths for application traffic, replication between instances and the backup target, including the namespaces and network policies that allow each one.
Supported PostgreSQL major version
Choose a major version that stays inside its support window for the expected life of the cluster. PostgreSQL 14 is supported until November 12, 2026, 15 until November 11, 2027, 16 until November 9, 2028, 17 until November 8, 2029 and 18 until November 14, 2030. Minor updates replace executables and restart, while major upgrades need pg_upgrade or logical replication, so plan that path now and confirm the image tags the operator supports for your chosen version.
Object storage and credentials
Base backups and WAL archives for point-in-time recovery go to object storage, so you need a bucket, a retention policy and credentials scoped only to that bucket. Kubernetes Secrets are stored unencrypted in etcd by default, so confirm encryption at rest is enabled or use an external store through the Secrets Store CSI Driver. Confirm versioning, object lock and region settings with your storage administrator before the first backup runs.
Team skills for day-two operations
Someone on your team needs working knowledge of Kubernetes RBAC, persistent volumes, PostgreSQL replication and PostgreSQL restore procedures. Running the cluster also means reading operator events, rotating credentials and running restore drills on a schedule. Name the people who will hold these duties after installation, and decide whether they stay in-house or are covered by a support agreement, because staffing is the cost that recurs after the build ends.
When a VM-based PostgreSQL cluster is still simpler
The decision is not whether PostgreSQL can run on Kubernetes with CloudNativePG. It can. The decision is whether your organization gains more from a shared Kubernetes operating model than it pays in additional moving parts for this one database. For some teams the answer is a virtual machine cluster with streaming replication, an external failover tool and object storage backups, and that setup is often the simpler choice. Make the decision explicitly, with the people who will be paged at night, before the cluster design starts.
A VM-based cluster is simpler in four situations. First, the team has little or no Kubernetes operations experience. A CloudNativePG cluster depends on the operator, the custom resources, pod scheduling, persistent volume claims and the Kubernetes API, and an on-call engineer must understand how these interact during a failover. Second, storage performance is sensitive and the storage layer is not well understood. Database latency depends on how the CSI driver, the storage class and the underlying array or software-defined storage behave under load, and a VM with directly managed disks removes one layer of indirection. Third, the platform already uses a VM-based standby pattern, so the existing runbooks, monitoring, backup jobs and staff skills cover the database without a second model. Fourth, the database must be isolated from a shared cluster control plane, for example because a regulator, a data owner or an internal risk function requires that a database outage cannot be caused by a cluster-level change.
Kubernetes adds real value in some of the same areas. Declarative state means the desired Cluster resource in version control describes the topology, PostgreSQL parameters, storage size and backup configuration, and the operator reconciles the running cluster toward it. Rolling changes let the operator replace standbys first and switch over the primary in a controlled order, which matters for minor updates. One operating model means the same tooling, policies, access reviews and deployment pipelines apply to the database as to the applications around it. These benefits are most visible when many teams run many databases on one platform.
The operational load is also real and must be planned for. The Kubernetes control plane stores its state in etcd, so the team must understand etcd backups, membership and quorum, and the cluster's own upgrade cadence. Storage becomes a platform dependency with its own failure modes, snapshot behavior and capacity planning. Network policy must allow replication, operator traffic, backup access and client connections while blocking everything else, and Pod Security Standards and Secrets encryption at rest must be configured for the namespace. Each of these layers has its own upgrade schedule, so the team upgrades Kubernetes and PostgreSQL on separate calendars. Ask the partner or internal team to write down who owns each layer, how each is tested before an upgrade, and what happens to the database during a control plane incident.
A practical test: if the team cannot yet describe how a failed primary is promoted, how the storage class is expected to behave, and how an etcd restore would affect the database, a VM-based cluster with well-tested runbooks is the lower-risk starting point. Plan a path to Kubernetes later if the platform grows. Note that the CloudNativePG documentation and your Kubernetes distribution's release notes should be checked for the versions you intend to run before any of these conclusions are final.
Configuring a CloudNativePG cluster in sequence
This sequence takes a CloudNativePG cluster from version checks to a tested restore and a pooled client path. Each step ends with a check, so the team confirms one layer works before the next layer depends on it. The order matters because backups, failover and access controls all rely on storage and RBAC decisions made early.
Confirm versions and compatibility
Your platform team confirms the Kubernetes version against the releases the Kubernetes project still maintains, then reads the Kubernetes version skew policy to see which control plane and node versions may differ. The database owner chooses a PostgreSQL major version still in its support window. PostgreSQL 18 is the newest major version, and PostgreSQL 14 reaches end of support on November 12, 2026, according to the PostgreSQL versioning policy. Check the operator release notes for supported Kubernetes and PostgreSQL combinations. Done when a written version matrix is signed off by the platform and database owners.
Install the operator with least-privilege RBAC
Install the operator into its own namespace using the method your platform team has approved. Review the ClusterRole and RoleBindings the operator requests, and remove any broad access your policy does not allow. Pay close attention to permissions on Secrets, because Kubernetes stores Secrets unencrypted in etcd by default and the good practices guidance recommends encryption at rest and restricted list and watch access. Confirm the namespace's Pod Security Standards level fits what the operator pods need. Done when the operator pod runs, its logs show no permission errors, and a test request into a namespace the operator should not manage is refused.
Define storage classes and object storage credentials
The infrastructure team selects storage classes that support the volume mode, expansion and reclaim behavior your design needs. Create the object storage bucket for base backups and WAL archives, and confirm the provider supports any retention or object lock feature your policy requires. Store the bucket credentials as Kubernetes Secrets, or pull them from an external store through the Secrets Store CSI Driver if your policy requires it. Limit which namespaces can read those credentials. Done when a test pod writes and reads an object in the bucket with the credentials, and a test volume binds to the chosen storage class.
Declare the cluster and its replication
Write the Cluster resource with the number of instances, the replication mode and resource requests and limits. Synchronous replication makes each commit wait for standbys, which trades some write latency for a lower chance of losing committed data. Asynchronous replication avoids that wait but can lose the most recent commits on failover. The business owner and the database team should decide this together. Set pod anti-affinity so instances land on different nodes or zones where your topology allows. Done when the cluster status reports a healthy state, every instance is ready, and exactly one primary is elected.
Verify replication and read-only standby behavior
Check that each standby is streaming changes from the primary and that replication lag is within the tolerance your team set. Write a test row on the primary and confirm it appears on a standby. PostgreSQL hot standby servers serve read-only queries, so attempt a write against a standby and confirm it is refused. Then run a controlled failover by removing the primary pod. PostgreSQL does not detect primary failure or promote a standby by itself, so confirm in the operator documentation how promotion is triggered and observed. Done when a replica is promoted, the test row survives, and the write path returns to the new primary.
Configure scheduled backups to object storage
Configure the backup schedule, retention policy and continuous WAL archiving to the bucket created earlier. Point-in-time recovery depends on a base backup plus the archived WAL files that follow it, so the archive must be continuous from the first backup onward. If your design uses incremental backups, confirm how the operator uses pg_basebackup and pg_combinebackup to build them. Check that the retention window matches the recovery commitments your organization has agreed to. Done when the first scheduled backup completes, WAL segments appear in the bucket, and the backup listing shows a base backup with an unbroken archive.
Run a restore test in a separate namespace
Restore the backup into a new namespace, never over the live cluster. Choose a recovery target time that falls after a known set of test writes, then start the restored cluster and query for those writes. Compare row counts or application-level checksums against what you expected. Record the measured restore time, since that figure is the only reliable input for planning recovery objectives. Remove the test namespace after the review and keep the results with the change record. Done when the restored cluster starts, the data matches the expected state at the chosen target time, and the measured restore time is documented.
Configure client access through a connection pooler
Deploy PgBouncer in front of the primary service and point applications at the pooler rather than directly at the database. Use SCRAM password authentication, because PostgreSQL 18 deprecates MD5 password authentication in favor of SCRAM. Enable TLS between applications and the pooler, and set pool sizes and connection limits based on what the database can handle. Keep PgBouncer on a current release, since version 1.26.1 was released on October 14, 2026 with security fixes. Done when an application connects through the pooler, pooler statistics show the traffic, and the application reconnects after the failover test from the replication step.
How failover, backups and point-in-time recovery fit together
PostgreSQL provides the building blocks for high availability but not the decision logic. Hot standby servers receive changes from the primary, answer read-only queries and can be promoted, yet PostgreSQL does not detect that a primary has failed and notify its standbys. Something outside the database has to make that call. In CloudNativePG, the operator watches each instance, decides when the primary is unhealthy, chooses a replica to promote and repoints the client-facing services at the new primary. Confirm, for the release you plan to run, how failure is detected, which health checks and timeouts apply, and how the former primary is stopped or fenced so it cannot accept writes after promotion. Verify these by simulating a node loss in a staging cluster and recording what the applications saw.
The replication mode determines what a failover can lose. With synchronous replication, a commit returns only after the configured standbys confirm the write, so a promoted standby holds every transaction the application saw acknowledged. The cost is commit latency that depends on the network between instances, and writes can stall when too few standbys are healthy. With asynchronous replication, the primary commits without waiting, so commit latency is lower and the primary keeps accepting writes when standbys fall behind. The cost is that transactions committed on the primary but not yet sent to a standby can be lost on failover. Decide this per workload and record the acceptable data loss for each system. Confirm in the operator documentation which settings control the number of synchronous standbys and what happens when fewer standbys are available than the setting requires.
Point-in-time recovery combines a base backup with archived WAL. The base backup is a full physical copy of the data directory taken at one moment, and the archived write-ahead log records every change after it. A restore can replay forward to a chosen time, such as just before a faulty migration ran. The two pieces depend on each other: a base backup without continuous WAL archiving only restores to the moment it was taken, and a WAL archive without a usable base backup cannot be replayed. Confirm that the operator writes both to object storage outside the cluster, so a lost node or volume does not take the backups with it. Also confirm how retention is enforced and how a recovery target time is requested. Then run a restore into a separate namespace on a schedule and measure how long it takes.
Incremental backups change the cost of frequent full copies. PostgreSQL's pg_basebackup can take incremental backups that record only changes relative to an earlier backup, and pg_combinebackup rebuilds a complete data directory from that chain at restore time. Smaller backups and shorter backup windows are the attraction. The trade-off is a longer restore path: every backup in the chain must be present and intact, and reconstruction must finish before WAL replay can begin. Decide the chain length, how long to keep incremental backups and how often to take a new full base backup. Confirm whether the CloudNativePG release you plan to run uses pg_basebackup incremental backups and pg_combinebackup, or takes full base backups only, and whether it combines them with the same WAL archive. Do not assume this from a PostgreSQL release note alone.
How Kubernetes identities, secrets and storage map to PostgreSQL
This table matches each Kubernetes object in a CloudNativePG deployment to the PostgreSQL or operator concept it controls, who usually owns it, and what to confirm before go-live. Read each row as a boundary: the platform team owns the declaration, the DBA owns database behavior, and the security team owns credential access. The main takeaway is that most failures come from unclear ownership of credentials and backup access, not from the database engine itself.
| Kubernetes object | PostgreSQL or operator concept | Owner | What to confirm |
|---|---|---|---|
| Cluster resource | The PostgreSQL cluster: desired instance count, PostgreSQL major version, storage, parameters and backup settings | Platform team declares it; DBA sets parameters | Operator version supports the PostgreSQL major version you plan to run, and the upgrade path for it |
| Pods | PostgreSQL instances: one primary and its standbys, each with its own process and data directory | Platform team | Scheduling rules keep the primary and standbys on separate nodes and zones |
| PersistentVolumeClaims | Data directory for each instance, provisioned through a storage class | Storage team with platform team | Storage class IOPS, volume expansion support, and what happens to data when a cluster is deleted |
| Secrets for superuser access | Superuser credentials used for administration and operator tasks inside the database | Security team with DBA | Who can read the Secret, how it is rotated, and whether etcd encryption at rest is enabled |
| Secrets for application users | Credentials for application roles that the database authenticates at connection time | Application team with DBA | How applications receive credentials, the rotation procedure, and whether an external secret store is used |
| ServiceAccounts and RBAC | Controls who can change the Cluster resource, trigger switchover, or start a restore | Platform team with security team | Least-privilege roles separate read access from change access, and API audit logs are retained |
| Object storage credentials Secret | Credentials the backup configuration uses to write WAL archives and base backups to the backup target | Security team and backup owner | Bucket policy is scoped to the cluster, and the restore identity is tested separately from the backup identity |
| PostgreSQL roles and pg_hba authentication | Database roles with SCRAM-SHA-256 passwords or client certificates, mapped to applications | DBA with application owners | Default auth methods in your operator version, and whether MD5 password authentication is disabled |
Securing PostgreSQL on Kubernetes: the controls that matter
A PostgreSQL cluster on Kubernetes depends on three layers: the control plane that stores Secrets and grants access, the namespace that runs database pods, and the database itself. The cards below cover the decisions to make before production data arrives and what to check for each. Use the CIS Kubernetes Benchmark as a shared reference for reviews, and note that DeployOpen prepares controls and evidence, while independent auditors and certification bodies issue any audit report or certification.
Encryption at rest for Secrets
Kubernetes stores Secrets unencrypted in etcd by default, and CloudNativePG keeps database credentials and backup access keys in Secret objects. Enable encryption at rest for the API server before the cluster holds production data, and confirm which key management option your distribution supports. Check that existing Secrets are rewritten after the setting changes, and that etcd snapshots are encrypted too, because backups copy the same data.
Least-privilege RBAC for Secret access
Anyone who can list or watch Secrets in a namespace can read every credential stored there. Grant operators, CI pipelines and monitoring tools only the verbs and resources they need, and avoid cluster-wide roles for database namespaces. Review bindings to the default service account and to the operator's own service account, then test them with access reviews before each release.
Pod Security Standards for the database namespace
Pod Security Standards define three profiles: Privileged, Baseline and Restricted. Apply the Restricted profile to the namespace that runs PostgreSQL pods, then check the operator and any sidecars against it, because a policy that blocks a required setting can stop instances from starting. Confirm which enforce, audit and warn modes you need, and record the namespace labels as evidence.
PostgreSQL authentication methods
Pg_hba rules decide how each client and role authenticates. Use SCRAM-SCRAM-SHA-256 for password logins, since PostgreSQL 18 deprecates MD5 password authentication. Certificate authentication suits service connections, while LDAP, GSSAPI and OAuth 2.0 (added in PostgreSQL 18) fit organizations that already run central identity. Confirm which methods your client libraries and connection pooler support before you tighten the rules.
TLS between clients and instances
Encrypt connections to the cluster's read-write and read-only services, and to any pooler in front of them, with TLS. Decide who issues server certificates, how they rotate, and whether clients verify the server certificate chain. Also decide whether replication traffic between instances is encrypted, and confirm that setting against your operator version. Encryption without client-side verification protects only against passive interception.
Backup encryption and object storage access
Backups hold the same data as the primary, so they need the same protection. Encrypt base backups and archived WAL before they reach object storage, and give the cluster a bucket-scoped credential that can write and read only its own prefix. Keep retention and deletion permissions with a separate identity, and test a restore using a decryption key held by the team that would run it.
Rolling updates and planned major upgrades
Minor PostgreSQL releases never change the internal storage format, so applying one means replacing the server executables and restarting the instance. No data conversion takes place, which makes minor updates the routine part of running the cluster. In a CloudNativePG cluster, the operator can roll a minor image change across the replicas first, then switch the primary, so each instance restarts once while a writable primary stays available for most of the window. Confirm in the operator documentation for your installed version how the image change, switchover order and pod restarts are sequenced, and whether your maintenance window must cover the restart of the final instance. PostgreSQL releases minor versions at least once every three months, so set a cadence that matches that rhythm. Test each minor image in a non-production cluster restored from a recent backup before it reaches production.
Major upgrades change the storage format, so they need a conversion step. PostgreSQL documents three routes: a logical dump with pg_dumpall and restore, pg_upgrade, and logical replication. The dump route is the simplest to reason about, but its outage grows with data volume. pg_upgrade converts the data directory directly, and PostgreSQL 18 retains planner statistics across major upgrades and adds parallel jobs and a --swap option, which reduces work at cutover. Logical replication works between different major versions and can keep a new cluster in sync until a short switch, which the PostgreSQL documentation describes as only several seconds of downtime. The cost is setup complexity, the need to carry schema changes and sequence values across deliberately, and a rollback path that depends on reverse replication. Choose the route for each database based on size, write rate and the downtime the business will accept.
Plan the target version against the PostgreSQL support windows. Version 14 is supported until November 12, 2026, and version 18 until November 14, 2030. Versions 15, 16 and 17 are supported until November 11, 2027, November 9, 2028 and November 8, 2029, respectively. Any cluster on version 14 needs a dated upgrade in the plan, because security fixes stop after that date. Confirm which PostgreSQL major versions your CloudNativePG release supports and which image tags are available in your registry, since operator support and PostgreSQL support are separate facts. Each major upgrade also requires application testing for query plans, extensions and driver behavior, and that testing often takes longer than the database step itself.
Kubernetes sets its own constraints on the order of work. The version skew policy requires kube-apiserver to be upgraded one minor version at a time and before kube-controller-manager, kube-scheduler and kubelets, and it allows kubelets to be up to three minor versions older than kube-apiserver. The Kubernetes project maintains the three most recent minor releases, so a platform that has fallen behind must upgrade several times in sequence. Check the current list on the Kubernetes releases page before you schedule work, because the supported set changes with each release cycle of roughly 14 weeks. Operator versions also declare the Kubernetes versions they support, so a Kubernetes upgrade may require a CloudNativePG upgrade first, or the reverse. Map both against your node pools, storage driver and backup tooling.
Plan the Kubernetes and PostgreSQL upgrades as separate tracks with their own owners, test environments and change records. Keep a single matrix that lists, for each environment, the Kubernetes minor version, the operator version, the PostgreSQL major and minor image, and the next dated end of support. Before either track starts, take a fresh backup and confirm that a restore works, because the rollback for a failed major upgrade often depends on the old cluster remaining intact. Run the Kubernetes change in a non-production cluster, then the PostgreSQL change, and avoid combining both in one window so that a failure has one cause to investigate.
Common failures in PostgreSQL on Kubernetes and how to fix them
This table lists the failures teams most often hit when running CloudNativePG clusters, with the likely cause, the fix and the check to run afterward. Read each row as a symptom you can observe, then work across to the cause and the verification step. The main takeaway is that most failures trace back to storage sizing, untested recovery paths, fencing, access control or upgrade order, and each one needs a test after the fix, not only a configuration change.
| Symptom | Likely cause | Fix | Verify afterward |
|---|---|---|---|
| Checkpoints spike and commit latency climbs during peak writes | The volume class cannot sustain WAL and checkpoint I/O at the peak write rate of the workload | Benchmark the storage class with a representative write load before go live, choose volumes with the IOPS and throughput the tests show are needed, and separate WAL storage if the design calls for it | Run a sustained load test and review WAL write and checkpoint metrics; confirm the storage class in the Cluster spec matches the class you tested |
| Standbys trail the primary during bulk writes and commits wait longer than expected | Synchronous replication waits on standbys with slower storage or a congested network, or the synchronous standby count is higher than the recovery design can absorb | Set the synchronous standby policy to match your data loss tolerance, place standbys in separate failure domains with comparable storage, and alert on replication lag | Repeat a bulk write test and confirm replay lag stays within the limit you set; compare commit latency before and after the change |
| After failover, two nodes accept writes or a former primary rejoins with diverged data | The failed primary was not isolated (fenced) before a standby was promoted, so the old instance could still accept connections | Confirm how the operator fences a failed primary before promotion, enable the fencing behavior its documentation describes, and limit who can delete pods or change volumes during an incident | Run a planned failover and a node-loss test; confirm the old primary refuses writes and rejoins only as a standby |
| Backup jobs report success but a restore fails or runs far longer than planned | Restore has never been exercised, WAL archive has gaps, bucket permissions changed, or the base backup was never validated | Schedule restore tests into a separate namespace or cluster, check WAL archive continuity as part of monitoring, and document the point-in-time recovery steps with the target time or transaction chosen in advance | Restore to a chosen recovery target and compare the restored data with expected row counts or checksums; record the restore time for the runbook |
| Database credentials can be read by service accounts or users who should not have access | RBAC grants list or watch on Secrets too broadly, and Secrets are stored unencrypted in etcd by default unless encryption at rest is configured | Enable encryption at rest for Secrets, restrict get, list and watch to the namespaces and service accounts that need them, and consider an external secret store through the Secrets Store CSI Driver | Run an access review of Secrets permissions and confirm encryption at rest is active on the API server; check that the operator still reads the credentials it needs |
| Applications hit connection limits, time out, and spike during failover | Each application opens direct connections to the primary, and no connection pooler is sized for the total connection demand | Place PgBouncer in front of the primary and read endpoints, size pool limits against the database connection limit, and set matching limits in each application | Measure connection counts and wait times under peak load; confirm applications reconnect through the pooler after a planned failover |
| Restores fail or behave differently after a PostgreSQL or operator upgrade | The upgrade runbook covers the cluster but not backups and restores, so the new version's restore path was never tested | Add a restore test to the upgrade checklist for both the operator and the PostgreSQL version, and choose the major upgrade method (pg_upgrade or logical replication) during planning, not during the change window | Restore a backup taken after the upgrade into a test cluster, then check extensions, application queries and planner behavior against the baseline |
| The cluster cannot be rebuilt after control plane loss, even though PostgreSQL volumes still exist | etcd snapshots were never scheduled for self-managed clusters, or the backup scope of a managed control plane was assumed rather than confirmed | For self-managed clusters, schedule etcd snapshots with etcdctl and test restores with etcdutl; for managed control planes, confirm in writing what the provider backs up and how restores are requested | Restore an etcd snapshot into a test control plane and confirm the CloudNativePG Cluster objects, Secrets and volume claims return and the operator reconciles them |
| Pods fail to schedule or operator features error after a control plane upgrade | Kubelets fall too far behind kube-apiserver, or control plane components were upgraded out of the order the version skew policy requires | Upgrade kube-apiserver one minor version at a time, then the controller manager, scheduler and kubelets, and check the CloudNativePG release notes for supported Kubernetes versions before each step | Compare component and node versions against the skew policy; run a single-node drain and a failover test after the upgrade completes |
Questions buyers ask before running PostgreSQL on Kubernetes
How much does running PostgreSQL on Kubernetes with CloudNativePG cost?
No single price applies, because cost follows the scope agreed in writing. The main drivers are the number of clusters, storage and backup design, the depth of the security review, the maturity of your Kubernetes platform and the number of environments that need the same setup.
One-time work includes design, build, restore testing and any migration from an existing database.
Recurring work includes operator and PostgreSQL upgrades, backup monitoring and support if you choose a retainer.
Ask for each category as its own line, with the environments covered, the client dependencies, the acceptance criteria and the exclusions. DeployOpen does not publish a price list. A quote follows from the written scope.
How long does a PostgreSQL on Kubernetes implementation take?
No fixed duration applies until the scope is written, and the schedule depends on that scope. The main drivers are the state of your Kubernetes platform, whether storage and an object store for backups already exist, how many clusters and environments are in scope and how long your change and access approvals take.
Restore testing is the step teams most often underestimate, because a backup that has never been restored into a test cluster has not yet been proven. Ask the partner to show the phases, the milestones that depend on your approvals and the work your team must deliver before each phase starts. Confirm your change windows and account access early, since they often set the pace more than the build does.
Can our own team run PostgreSQL on Kubernetes without a partner?
Yes, many teams can, provided they already run Kubernetes and PostgreSQL in production and can own the failure modes. Your team needs to understand streaming replication, synchronous and asynchronous commit behavior, WAL archiving, point-in-time recovery, connection pooling and the upgrade paths for both the operator and PostgreSQL.
PostgreSQL itself does not detect a failed primary and promote a standby, so the operator's failover logic becomes part of daily operations. Your staff must understand that logic in detail. A common middle path is a partner-led design and first build, followed by internal ownership with a documented runbook. Decide early which parts your team will run after handover and which parts you want supported under a retainer.
Does this work require in-house Kubernetes expertise?
Yes, at least one person on your side needs working Kubernetes knowledge to review changes and respond to incidents. The operator automates much of the database lifecycle, but it runs on your cluster and inherits its behavior.
Your staff should understand storage classes, node scheduling, pod disruption behavior during node drains, RBAC and how secrets are handled. Kubernetes stores Secrets unencrypted in etcd by default, so encryption at rest and tight access controls belong in the design. Your team also needs to know how the control plane is backed up, because database backups alone do not rebuild a broken cluster. Plan for that knowledge to be documented and shared across more than one person.
What breaks most often when PostgreSQL runs on Kubernetes?
The most common failures come from storage, backups that were never tested and capacity limits that appear under load. Typical examples include volume attach delays after a node failure, replication lag during heavy writes, connection exhaustion when applications open too many direct connections and node drains that interact badly with replicas.
Backups can fail quietly when WAL archiving stops, so alerting on archive failures matters as much as the backup job itself. Version drift is another source of trouble. Kubernetes releases arrive roughly three times a year, and the project maintains only its three most recent minor releases, so upgrade planning is ongoing. Ask for a failover test, a restore test into a separate cluster and a documented runbook before go-live.
When is a VM-based PostgreSQL cluster still simpler than Kubernetes?
A VM-based cluster is often simpler when you have few databases, no Kubernetes platform team and well-established tooling for virtual machines. It removes a layer you would otherwise have to operate.
VMs still need failover tooling, backup and restore procedures, patching and monitoring, so the database work does not disappear. Kubernetes becomes worth its extra moving parts when you already run it, want declarative cluster definitions across environments and have people who can manage the platform. The Kubernetes project maintains its three most recent minor releases, so the platform itself needs upgrades on a steady schedule. Compare both options on the same operational tasks: failover, restore, upgrade and on-call effort.
What should a written quote for PostgreSQL on Kubernetes include?
A written quote ties each price line to a defined scope. Include the clusters and environments in scope, the Kubernetes distribution and version assumptions, the storage and object store used for backups, the retention period and recovery targets, and the definition of a passed restore test.
Separate one-time work (design, build, restore testing, migration) from recurring work (upgrades, backup monitoring, support). List the security review scope, what you must provide and when, the acceptance criteria, the exclusions and how changes are handled after signature. DeployOpen plans, builds and documents this work inside the client's own infrastructure, and most engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
How DeployOpen scopes, builds and supports PostgreSQL on Kubernetes
DeployOpen plans, implements, hardens, documents and supports self-hosted open-source platforms inside your own cloud accounts, data centers or air-gapped networks. For PostgreSQL on Kubernetes with CloudNativePG, that means the cluster design, operator configuration, backup and recovery approach and runbooks are agreed in writing before the build starts, and engagements are fixed-scope.
How we scope
- The written scope names the Kubernetes distribution, cluster topology and PostgreSQL major version before any work begins.
- We record which backup target, retention period and recovery objectives your team has agreed to, so the build has a clear target.
- Authentication, network access, secrets handling and PgBouncer pooling decisions are listed as in or out of scope for each deliverable.
How we build
- Clusters are defined declaratively and deployed to your environment, with failover and replication tested before handover.
- Object storage backups are configured and a point-in-time recovery test is run against a restored copy, not only a successful backup job.
- Rolling update and planned major upgrade procedures are rehearsed in a non-production environment that mirrors your cluster.
How we hand over
- You receive architecture and configuration documentation covering the operator, storage classes, backup schedules and access model.
- Runbooks cover failover checks, restore steps, scaling, and the sequence for Kubernetes and PostgreSQL upgrades in your environment.
- Handover includes a walkthrough with your platform and database staff so they can operate the cluster without outside help.
How we support
- Ongoing support, upgrades and continuous testing are available as a retainer, with the response expectations written into that agreement.
- Periodic restore tests and review of backup and failover evidence are included in the retainer scope when you agree to them.
- Upgrades of the operator, Kubernetes and PostgreSQL minor and major versions are planned against the release calendar and your change windows.

