Skip to main content

Rob Pankow Rob Pankow

Redis on Kubernetes: Persistent Storage Architecture and High Availability

Jun 22, 2026  |  12 min read

Last edited: Jul 13, 2026

Redis on Kubernetes: Persistent Storage Architecture and High Availability

Redis is the most widely deployed in-memory data store in the world, and running it on Kubernetes is increasingly common for teams that want a unified platform for both stateless services and stateful workloads. Unlike a pure in-memory cache that accepts total data loss on restart, production Redis deployments almost always enable persistence: either the AOF log, RDB snapshots, or both together. That persistence decision transforms Redis from a network-attached hash table into a storage-sensitive workload with write patterns that interact directly with Kubernetes scheduling constraints.

Getting storage right for Redis on Kubernetes means understanding both the persistence write path and the scheduling model. These two interact in ways that create operational problems if you start with local disk and discover the constraints only when a node drains or fails unexpectedly.

Why Redis Storage Is Demanding on Kubernetes

Redis supports two persistence mechanisms, and each makes different demands on the underlying storage:

Append-Only File (AOF): Redis writes every write command to an append-only log file. The appendfsync setting controls when the kernel’s write buffer is flushed to disk:

  • appendfsync always: every command triggers an fsync call before Redis acknowledges the write. This is the most durable mode and the most storage-latency-sensitive, because fsync blocks until the write reaches durable media.
  • appendfsync everysec (the default): Redis calls fsync once per second, batching commands between flushes. This mode tolerates up to one second of data loss on a crash and is less latency-sensitive, but still requires storage that can sustain continuous sequential writes.
  • appendfsync no: the OS decides when to flush. This delivers the best throughput but offers no durability guarantees beyond what the kernel provides.

RDB snapshots: Redis periodically forks a child process to write a point-in-time snapshot of the entire dataset to a .rdb file. The fork is near-instant (copy-on-write), but the child process writes the full dataset sequentially to disk. On a large dataset (tens of gigabytes), this produces a burst of sequential write I/O that saturates storage for the duration of the snapshot. If storage delivers inconsistent throughput under burst, the snapshot write slows, the fork period extends, and the Redis process accumulates copy-on-write memory overhead during the delay.

The combined I/O profile on a production Redis node running AOF with RDB backup is:

  • Continuous low-volume sequential writes from the AOF log (fsync-gated at everysec or always)
  • Periodic high-volume sequential write burst from RDB snapshot generation
  • Sequential reads during restart and replica sync for AOF replay or RDB load

On Kubernetes, these storage requirements combine with a scheduling problem. Redis runs as a Kubernetes StatefulSet with persistent storage attached to each pod. If that storage is local NVMe (hostPath or local PersistentVolumes), the pod becomes pinned to the node where the disk lives. When the node drains for maintenance or fails unexpectedly, the pod cannot reschedule until the node returns or the data is manually migrated.

Persistent Volume Architecture for Redis StatefulSets

Redis on Kubernetes requires one persistent volume claim per replica at minimum, and ideally two per replica: one for the data directory (AOF log and RDB snapshot) and one for the AOF rewrite buffer if you want to isolate the rewrite burst from the live log I/O. For most teams, a single PVC per replica is the practical starting point, with the data directory containing both the .aof and .rdb files.

The StatefulSet pattern uses volumeClaimTemplates to provision a PVC per replica automatically. Each Redis pod gets its own volume, independent of other replicas. Redis does not support shared data access between replicas (primary and replica maintain independent datasets that are synchronized at the command level), so ReadWriteOnce access mode is correct.

Storage AttributeRecommended ValueReason
Volume modeFilesystemRedis manages its own file layout; raw block mode offers no benefit
Access modeReadWriteOnceOne pod per volume; Redis does not support shared data access
Volume bindingWaitForFirstConsumerEnsures the volume is provisioned in the scheduler’s chosen zone
Reclaim policyRetainPrevents accidental data loss when a pod or StatefulSet is deleted
Allow expansiontrueOnline capacity growth without pod restart (requires CSI driver support)
IOPS provision3,000–15,000 IOPSeverysec mode can run on 3k IOPS; always mode needs 10k or more

Table 1: Persistent volume configuration recommendations for Redis StatefulSets on Kubernetes.

A minimal StorageClass for Redis on Kubernetes using a CSI driver looks like this:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: redis-nvme
provisioner: csi.simplyblock.io
parameters:
replication: "2"
compression: "false"
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

The volumeClaimTemplates section of the StatefulSet references this StorageClass:

volumeClaimTemplates:
- metadata:
name: redis-data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: redis-nvme
resources:
requests:
storage: 50Gi

The volumeBindingMode: WaitForFirstConsumer is critical: without it, the PVC binds in a random zone before the pod is scheduled, often ending in a zone mismatch that prevents the pod from starting.

Running Redis on Kubernetes and hitting AOF write latency or snapshot slowdowns? simplyblock’s disaggregated NVMe/TCP storage delivers consistent sub-millisecond fsync latency without credit-burst limits, and lets Redis pods reschedule freely across nodes. Talk to a storage architect

AOF and RDB: Persistence Modes and Their Storage Impact

Choosing between AOF and RDB (or combining them) is the most consequential Redis configuration decision for persistent storage sizing and StorageClass selection. The right choice depends on your recovery point objective, your dataset size, and the write rate of your application.

Persistence ModeWrite PatternIOPS RequirementData Loss RiskRecovery Time
AOF alwaysEvery command: synchronous fsyncVery high (10k+ for busy workloads)Zero (each command durable)Fast (replay log from last fsync)
AOF everysec (default)Continuous sequential, 1 fsync/secModerate (3k–8k)Up to 1 secondFast (replay from last second)
RDB onlyBurst sequential on snapshot scheduleLow baseline, high burstMinutes to hours (since last snapshot)Moderate (load full .rdb file)
AOF + RDBBoth patterns combinedHighest overallNear-zero (AOF), plus periodic checkpointFastest (use RDB as base, replay AOF delta)

Table 2: Redis persistence mode comparison for Kubernetes storage planning.

For teams running Redis as a cache where data loss is acceptable, disabling both AOF and RDB is valid: the pod consumes no storage at all and can be scheduled anywhere. But for Redis used as a primary data store (session state, rate limiter, leaderboard, queue), AOF is mandatory, and the storage must handle the fsync rate of your application’s write throughput.

The AOF rewrite process (triggered automatically when the AOF file grows beyond a configured size) creates a temporary rewrite file and then atomically renames it over the existing AOF. During the rewrite, Redis buffers new write commands in memory and flushes them to the new file before the rename. This process is CPU-bound and I/O-bound simultaneously. On a node with local NVMe, the rewrite competes with foreground AOF writes for disk bandwidth. With disaggregated storage, the rewrite I/O goes to the same network-attached pool, where throughput is shared across all volumes but not artificially capped.

Diagram showing Redis StatefulSet pods on Kubernetes nodes, each connecting to their own NVMe/TCP volume in a disaggregated simplyblock storage pool, with AOF and RDB data stored separately from compute nodes
Figure 1: Redis StatefulSet pods connect to persistent volumes in a disaggregated NVMe/TCP storage pool. Pod scheduling is free because the storage is not pinned to any compute node.

High Availability: Redis Sentinel and Redis Cluster

Redis supports two distinct high availability topologies, and each has different persistent storage requirements on Kubernetes.

Redis Sentinel is the standard HA approach for a single Redis keyspace. A Sentinel deployment consists of one Redis primary, one or more Redis replicas, and three or more Sentinel processes (which are stateless monitors and do not need persistent volumes). The Sentinels agree on a quorum when the primary is unreachable and promote the most up-to-date replica to primary. Each replica pod needs its own PVC because it maintains an independent copy of the dataset.

Redis Cluster shards the keyspace across multiple primary nodes (six nodes minimum: three primaries and one replica per primary). Each primary owns a subset of the 16,384 hash slots and has its own dataset. Each Cluster member (primary and replica) needs its own PVC. Clients route commands to the correct shard using the CLUSTER REDIRECT protocol or a client-side routing library.

HA ModelNode Failure RecoveryStorage RequirementScheduling Flexibility
Local NVMe + Sentinel failoverPod waits for node return or manual re-syncLow per-node cost, high over-provision ratioPod pinned to node with data
Cloud block storage (gp3, Premium SSD)Pod reschedules; volume reattaches (slow in multi-AZ)Per-GB and per-IOPS pricing, burst limits applyZone-bound; multi-AZ attach adds latency
Disaggregated NVMe/TCP (simplyblock)Pod reschedules; volume reattaches in secondsFlat pool pricing, no per-volume IOPS capsAny node in the cluster

Table 3: High availability model comparison for Redis on Kubernetes.

With local storage, a Redis primary failure in a Sentinel deployment triggers a failover to a replica, but the failed primary’s pod cannot reschedule until the node returns. The old primary’s PVC is stuck on the failed node. In a Redis Cluster, the situation is the same: a shard primary that was on a failed node cannot restart until the node recovers, and the cluster operates in degraded mode (reads can be served by the replica that was promoted, but the failed primary’s slot assignments are unavailable until failover completes and the old primary slot range is transferred).

Disaggregated storage removes this constraint entirely. When a node drains or fails, the Redis pod reschedules on any available node. The CSI driver re-attaches the same PVC to the new node. Redis performs AOF replay or loads the RDB snapshot and resumes operation. For a Sentinel primary, this means the node failure duration is the time it takes Kubernetes to detect the failure (typically 40 to 60 seconds with default kubelet settings) plus the AOF replay time, not the time to repair or replace hardware.

For Redis Cluster, each shard member uses the same StatefulSet and volumeClaimTemplates pattern. The operator (Spotahome Redis Operator, Bitnami Helm chart, or Redis Operator by OT-Container-Kit) manages cluster membership and slot rebalancing at the database layer. The storage layer handles durability and replication independently.

Snapshot-based point-in-time recovery is a further advantage of the storage layer approach. simplyblock’s CSI external snapshotter integration allows you to take a consistent storage snapshot of a Redis data volume in seconds, without pausing AOF writes. Restoring from snapshot brings the dataset back to a known-good state significantly faster than replaying a full AOF log from an old backup.

Questions and Answers

What persistent storage settings work best for Redis on Kubernetes?

Use volumeBindingMode: WaitForFirstConsumer to prevent zone mismatches, reclaimPolicy: Retain to prevent accidental data loss on PVC deletion, and allowVolumeExpansion: true for online capacity growth. For IOPS, the requirement depends on the AOF fsync mode: appendfsync everysec (the default) needs 3,000 to 8,000 IOPS per node for most workloads; appendfsync always needs 10,000 or more. RDB-only mode needs burst IOPS headroom on the snapshot schedule but modest sustained IOPS otherwise.

How does AOF appendfsync always affect storage latency on Kubernetes?

With appendfsync always, Redis calls fsync after every write command before acknowledging the client. If the storage volume introduces tail latency on fsync (common with cloud block storage that has burst IOPS credit limits), each Redis write stalls until the fsync completes, and application latency grows. The solution is storage that delivers consistent, low-latency fsync without burst credit models: NVMe/TCP disaggregated storage removes the burst model and delivers fsync latency in the sub-millisecond range on a well-tuned 25 GbE link.

Can Redis pods reschedule freely with NVMe/TCP persistent storage?

Yes. NVMe/TCP volumes are network-attached and not bound to any physical node. When a Redis pod reschedules (node drain, node failure, or normal pod eviction), the CSI driver re-attaches the persistent volume to the new node. Redis replays the AOF log (or loads the RDB snapshot) and resumes operation. For appendfsync everysec, AOF replay of up to one second of commands completes in well under one second. For RDB-only mode, startup time depends on dataset size but not on data migration across the network.

How does simplyblock compare to local NVMe for Redis on Kubernetes?

Local NVMe delivers the lowest absolute latency but pins the Redis pod to a specific node, complicates Sentinel failover after node failure, and requires node-level RAID for durability. simplyblock’s disaggregated NVMe/TCP storage delivers latency in the 100 to 400 microsecond range on 25 GbE, which is within the acceptable range for appendfsync everysec and even appendfsync always on moderate write rates. The scheduling flexibility and storage-layer replication reduce the operational burden significantly for teams running Redis Sentinel or Cluster.

Does this architecture work for Redis Cluster deployments?

Yes. A Redis Cluster is composed of multiple shard primaries, each with one or more replicas. Each member uses the same StatefulSet and volumeClaimTemplates pattern: every pod gets its own PVC provisioned from the shared NVMe pool. Cluster membership, hash slot assignment, and failover are managed by Redis Cluster itself or by a Kubernetes operator. The storage layer handles durability and replication at the volume level, independently of Redis Cluster’s replication. Adding a new shard to the cluster requires adding pods and their PVCs, without adding Kubernetes nodes or storage hardware.

You may also like:

NVMe/TCP vs NVMe/RoCE for Kubernetes Storage: Choosing the Right Fabric
NVMe/TCP vs NVMe/RoCE for Kubernetes Storage: Choosing the Right Fabric

NVMe over Fabrics gives Kubernetes clusters low-latency block storage over the network. The transport you pick, TCP or RoCE, determines your latency floor, infrastructure cost, and operational complexity. Here is how to choose.

We Break Our Storage So You Never Have To
We Break Our Storage So You Never Have To

Simplyblock runs 100+ hours of automated chaos engineering before every release: real NVMe hardware, real FIO workloads, four failure types injected under live load. This is what we test, why it is necessary, and what it means for your infrastructure.

NVMe Storage Cost Optimization in 2026: Erasure Coding, Thin Provisioning, and Compute Efficiency
NVMe Storage Cost Optimization in 2026: Erasure Coding, Thin Provisioning, and Compute Efficiency

NVMe drives deliver the performance Kubernetes stateful workloads need, but triple replication and thick provisioning multiply their cost fast. Here is a practical breakdown of erasure coding economics, thin provisioning, and how sub-millisecond latency reduces compute waste.