This post was originally published in 2023, and we’ve updated it in 2025 for clarity and relevance, reflecting current practices while honoring its original perspective.

Running PostgreSQL on Kubernetes promises flexibility, but storage decisions can quickly make or break your deployment. From balancing cost with performance to ensuring high availability, every choice adds complexity. That’s why there are multiple storage strategies for PostgreSQL on Kubernetes in Percona Operator for PostgreSQL, giving you a path to configure for your unique needs without locking into rigid, proprietary solutions.

In this post, we’ll walk through different storage strategies, starting with the basics and moving into more advanced approaches, to help you build a setup that scales.

Basic storage strategies for PostgreSQL on Kubernetes

Setting StorageClass

StorageClass resource in Kubernetes allows users to set various parameters of the underlying storage. For example, you can choose the public cloud storage type – gp3, io2, etc, or set file system.

You can check existing storage classes by running the following command:

As you see standard-rwo is a default StorageClass, meaning that if you don’t specify anything, the Operator will use it.

To instruct Percona Operator for PostgreSQL which storage class to use, set it the spec.instances.[].dataVolumeClaimSpec section:

Storage strategy: using a dedicated volume for PostgreSQL WALs on Kubernetes

Write-Ahead Logs (WALs) keep the recording of every transaction in your PostgreSQL deployment. They are useful for point-in-time recovery and minimizing your Recovery Point Objective (RPO). In Percona Operator, it is possible to have a separate volume for WALs to minimize the impact on performance and storage capacity. To set it, use spec.instances.[].walVolumeClaimSpec section:

If you enable walVolumeClaimSpec, the Operator will create two volumes per replica Pod – one for data and one for WAL:

Expanding storage for PostgreSQL on Kubernetes clusters

If your StorageClass and storage interface (CSI) supports VolumeExpansion, you can just change the storage size in the Custom Resource manifest. The operator will do the rest and expand the storage automatically. This is a zero-downtime operation and is limited by underlying storage capabilities only.

Adjusting storage classes for PostgreSQL on Kubernetes

It is also possible to change the storage capabilities, such as filesystem, IOPs, and type. Right now, it is possible through creating a new storage class and applying it to the new instance group. 

Creating a new instance group replicates the data to new replica nodes. This is done without downtime, but replication might introduce additional load on the primary node and the network. 

There is work in progress under Kubernetes Enhancement Proposal (KEP) #3780. It will allow users to change various volume attributes on the fly vs through the storage class. 

Ensuring data persistence in PostgreSQL on Kubernetes

Finalizers

By default, the Operator keeps the storage and secret resources if the cluster is deleted. We do it to protect the users from human errors and other situations. This way, the user can quickly start the cluster, reusing the existing storage and secrets.

This default behavior can be changed by enabling a finalizer in the Custom Resource: 

This is useful for non-production clusters where you don’t need to keep the data. 

Protecting PostgreSQL data with Kubernetes StorageClass policies

There are extreme cases where human error is inevitable. For example, someone can delete the whole Kubernetes cluster or a namespace. Good thing that StorageClass resource comes with reclaimPolicy option, which can instruct Container Storage Interface to keep the underlying volumes. This option is not controlled by the operator, and you should set it for the StorageClass separately. 

In this case, even if Kubernetes resources are deleted, the physical storage is still there.

Using regional disks for PostgreSQL on Kubernetes

Regional disks are available at Azure and Google Cloud but not yet at AWS. In a nutshell, it is a disk that is replicated across two availability zones (AZ).

Kubernetes Regional disks

To use regional disks, you need a storage class that specifies in which AZs will it be available and replicated to:

There are some scenarios where regional disks can help with cost reduction. Let’s review three PostgreSQL topologies:

  1. Single node with regular disks
  2. Single node with regional disks
  3. PostgreSQL Highly Available cluster with regular disks

If we apply availability zone failure to these topologies, we will get the following:

  1. Single node with regular disks is the cheapest one, but in case of AZ failure, recovery might take hours or even days – depending on the data.
  2. With single node and regional disks, you will not be spending a dime on compute for replicas, but at the same time, you will recover within minutes. 
  3. PostgreSQL cluster provides the best availability, but also comes with high compute costs.
Single PostgreSQL node, regular disk Single PostgreSQL node, regional disks PostgreSQL HA, regular disks
Compute costs $ $ $$
Storage costs $ $$ $$
Network costs $0 $0 $
Recovery Time Objective Hours Minutes Seconds

Leveraging local storage for PostgreSQL on Kubernetes

One of the ways to reduce your total cost of ownership (TCO) for stateful workloads on Kubernetes and boost your performance is to use local storage as opposed to network disks. Public clouds provide instances with NVMe SSDs that can be utilized in k8s with tools like OpenEBS, Portworx, and more. The way it is consumed is through regular storage classes and deserves a separate blog post.

Kubernetes Local storage

Bringing your PostgreSQL storage strategy together

Choosing the right storage strategy is a big step toward running PostgreSQL effectively on Kubernetes, but it’s only part of the challenge. Scaling deployments, automating operations, and keeping costs predictable all add to the daily pressure on your team. That’s where Percona can help.

We’ve put together a guide that shows how to take the complexity out of PostgreSQL in the cloud with automation, scalability, and zero lock-in. Explore it here:

 

storage strategies for PostgreSQL on Kubernetes

Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Adesoji Alu

Good ?