Whitepapers / Valkey on Kubernetes

Running Valkey on Kubernetes

Replication, Valkey Cluster, memory, and operators

Valkey keeps its whole dataset in memory, replicates asynchronously, and shards itself. That makes it easy to start on Kubernetes and easy to get subtly wrong. Most production incidents come down to three settings: memory limits, persistence, and how failover meets a pod that restarts in two seconds.

For SREs, platform engineers, and developers moving off Redis. Covers Valkey 8.1, 9.0, and 9.1. Updated .

1. Introduction: Valkey meets Kubernetes

Valkey is an in-memory key-value data store, used for caching, sessions, queues, rate limits, leaderboards, and more and more for vector search. It started in March 2024, when Redis moved away from its BSD license. Former Redis maintainers forked Redis 7.2.4 under the Linux Foundation, and Valkey has stayed under the BSD 3-Clause license since. It speaks the same protocol, so Redis clients and tools connect to it without code changes.

Valkey has since diverged in useful ways. Valkey 8.0 moved network I/O to a pool of threads. Valkey 8.1 replaced the main hash table and cut about 20 bytes from every key. Valkey 9.0 added atomic slot migration, per-field expiration in hashes, and numbered databases in cluster mode. AWS ElastiCache, Google Cloud Memorystore, and Aiven all offer it as a managed service.

Is Valkey on Kubernetes production-ready?

The database is. The tooling around it on Kubernetes is younger than the tooling for Redis, and that's what to evaluate.

The official Valkey operator is developed under the Valkey project and moves fast, but it's still pre-1.0 and says it isn't ready for production. Most Redis operators haven't added Valkey yet, and the ones that have often support only some topologies. Section 6 compares the options. Whatever you choose, test failover and restarts on your own cluster before you trust it with data, because that's where Valkey on Kubernetes surprises people. Section 2 shows how.

Teams run Valkey on Kubernetes for the usual reasons:

  1. It sits next to the applications it serves, with sub-millisecond latency and no data leaving the cluster.
  2. It avoids lock-in to ElastiCache, Memorystore, or Redis Cloud, and their per-node pricing. The same setup runs on any cloud or on-prem.
  3. It's the simplest way off Redis's newer licenses. Valkey is BSD-licensed, and the move is mostly a change of image.

Decide first: cache or data store

Almost every setting in this guide depends on one question: if Valkey lost all its data right now, would you rebuild it, or would you have lost something?

CacheData store
ExamplesQuery and page caches, LLM response caches, computed resultsSessions, queues and streams, counters, leaderboards, rate limits
When data is lostSlower responses while the cache refillsUsers log out, jobs disappear, counts reset
PersistenceNone. save "" and appendonly noAOF with appendfsync everysec
maxmemory-policyallkeys-lru or allkeys-lfunoeviction, so writes fail instead of data disappearing
ReplicasOptional, for read capacity and fast failoverAt least one per shard, in another zone
BackupsNot neededRDB snapshots to object storage

Many teams use one Valkey for both and end up with the worst of each: an eviction policy that silently drops sessions, or persistence overhead on a cache. Run separate instances.

Moving from Redis

Valkey is compatible with Redis 7.2, and most moves are uneventful. Check these first:

  • Modules. RedisJSON, RediSearch, and RedisBloom don't run on Valkey. The valkey-bundle image ships Valkey's own JSON, Bloom filter, search, and LDAP modules instead. Their commands are close but not identical, so test your queries.
  • Newer Redis features. Some commands and data types added after Redis 7.2, such as vector sets in Redis 8, aren't in Valkey. Hashes with per-field expiration from Redis 8 can't be migrated yet.
  • Moving the data. Replicate it rather than copying files. RedisShake connects to Redis as a replica, copies a snapshot, then streams changes until you cut over. In our tests it moved a 50 GiB Redis cluster in 11 minutes under live writes with zero keys missing, and the same data used 10 to 20% less memory on Valkey.

2. Valkey on Kubernetes architectures

Valkey runs in three shapes: a standalone instance, a primary with replicas, and Valkey Cluster, which shards data across several primaries. All replication in Valkey is asynchronous. That one fact drives most of this section.

TopologyFailoverScalesBest for
StandaloneNone. Kubernetes restarts the podVertically onlyDevelopment, and caches that can be rebuilt
Primary and replicas, with Sentinel or an operatorSentinel or the operator promotes a replicaReads, with replicasDatasets that fit in one node's memory
Valkey ClusterBuilt in. Replicas in each shard elect a new primaryReads and writes, with shardsLarge datasets, high write throughput

Primary and replicas

A primary accepts all writes and streams them to its replicas, which serve reads. Something outside the primary has to decide when to fail over. Traditionally that's Valkey Sentinel: three or more Sentinel processes watch the primary, agree that it's down, promote a replica, and tell clients where the new primary is. Clients ask Sentinel for the primary's address instead of connecting to a fixed one, so they need Sentinel support. Some operators replace Sentinel and fail over themselves, then point a Kubernetes Service at the new primary.

Valkey Cluster

Valkey Cluster splits the keyspace into 16,384 hash slots. Each key belongs to one slot, and each slot to one shard: a primary and its replicas. Nodes talk to each other over a cluster bus on the client port plus 10,000, usually 16379. When a primary stops responding for cluster-node-timeout, 15 seconds by default, its replicas hold an election and the winner takes over its slots. No Sentinel, no operator in the path. A failover needs votes from a majority of primaries, so a cluster needs at least three.

Clients have to be cluster-aware. They fetch the slot map, send each command to the shard that owns the key, and follow MOVED redirects when the map changes. Commands that touch several keys only work if all the keys are in the same slot. Hash tags force that: {user:42}:cart and {user:42}:profile hash only the part in braces, so they always share a slot.

Kubernetes cluster: 3 shards, 1 replica each, 3 availability zonesCluster-aware clientZone AZone BZone CShard 0 primaryShard 1 primaryShard 2 primaryShard 2 replicaShard 0 replicaShard 1 replicaslots 0-5460slots 5461-10922slots 10923-16383slots 10923-16383slots 0-5460slots 5461-10922PVC: AOF + RDBPVC: AOF + RDBPVC: AOF + RDBPVC: AOF + RDBPVC: AOF + RDBPVC: AOF + RDBSolid: primary. Dashed: replica of the shard with the same color. Nodes gossip on the cluster bus, port 16379
A three-shard Valkey Cluster spread across three zones. Each zone holds one primary and the replica of a different shard, so losing a zone loses no data and the surviving replica takes over. The client sends each key straight to the primary that owns its slot.

Resharding

Adding shards means moving slots, and the keys in them, to the new primaries. Before Valkey 9.0, keys moved one at a time with MIGRATE, and clients saw ASK redirects and failed multi-key commands while a slot was half-moved. Valkey 9.0 moves whole slots atomically: the target receives a snapshot and the changes after it, and ownership switches in one step.

It works. In our resharding test on a saturated cluster, going from 3 to 6 shards took about two minutes, nearly doubled throughput, and lost no acknowledged writes. Two things to watch. Scale out before you need to, because each primary executes commands on one thread and migration competes with your traffic for it. And scaling in can pile the drained slots onto one remaining shard before rebalancing, so leave memory headroom on every shard, not just on average.

Failover and the persistence trap

Because replication is asynchronous, a primary acknowledges a write before any replica has it. If the primary dies, writes it hadn't sent yet are lost. That window is usually milliseconds. On Kubernetes there's a worse failure that can lose far more, and it comes from pods restarting quickly.

When a Valkey container is killed, Kubernetes restarts it in a second or two. That's faster than cluster-node-timeout, so the cluster never declares the primary failed and no replica takes over. The restarted process still has its nodes.conf, so it rejoins as the primary, with whatever it loaded from disk. Its replica notices a primary with a different history, discards its own newer copy, and does a full resync from the primary.

1. Normal operation2. Primary killed, back in 2 s3. Replica resyncsPrimaryReplicaPrimary (restarted)ReplicaPrimaryReplica (full resync)writes to 12:00:30writes to 12:00:30RDB from 12:00:00writes to 12:00:30RDB from 12:00:00copy of 12:00:00Replica in syncBack before the 15 s node timeout,so no replica is promoted30 s of acknowledged writes goneon both nodes
Without AOF, a primary that restarts faster than cluster-node-timeout comes back with its last RDB snapshot, and its replica discards newer data to match it. With no persistence at all, it comes back empty and empties the replica too.

We reproduced this in our own testing. A force-killed primary without AOF lost 3,450 acknowledged writes, everything since its last snapshot. The same test with AOF and appendfsync everysec lost none, because the restarted primary reloaded every write from its AOF. In a separate memory test, a primary with no persistence was OOM-killed, restarted empty, and a replica resync wiped the replica too, while the cluster resource kept reporting Ready. The Valkey replication docs warn about exactly this.

The rules that follow:

  • For a data store, enable AOF on primaries and replicas. A primary should never restart with less data than its replicas.
  • For a pure cache, either accept that a restart empties the shard, or don't let a crashed primary come back as primary.
  • Use shutdown-on-sigterm failover (Valkey 9.0+), so that a drained or evicted primary hands its slots to a replica before it exits. In our tests the handoff usually took under a second.
  • Where losing a write matters, WAIT and WAITAOF let a client wait until replicas or disks have it. min-replicas-to-write stops a primary from accepting writes when its replicas fall behind. Neither makes replication synchronous, but both shrink the window.

Routing, DNS, and clients

Pod IPs change on every restart, so the addresses nodes announce in the slot map matter. With cluster-preferred-endpoint-type hostname, nodes announce stable DNS names from a headless Service, which TLS needs anyway for certificate checks. The catch is DNS caching. In our tests, CoreDNS kept returning a force-killed pod's old IP for 30 seconds, so clients kept failing for 30 seconds after the pod was back. A failover avoids this, because the slots move to a host that's already in DNS.

Clients differ more than you'd expect. In the same test, one benchmark tool stopped sending traffic after a primary was killed and never recovered, while the Python client retried and carried on. Test your actual client library through a failover and a reshard. Valkey GLIDE, the official client, and the main Redis cluster clients all handle redirects, but their retry and topology-refresh defaults vary.

Placement and disruptions

A primary and its replica must never share a node, or one node failure takes out the whole shard. With several shards, spread primaries too, so one node doesn't hold most of the write load. A PodDisruptionBudget with maxUnavailable: 1 keeps a node drain from evicting more than one Valkey pod at a time. In our drain test, it turned a node with two primaries on it into 114 seconds of one-at-a-time handoffs and zero failed writes.

topologySpreadConstraints:
- maxSkew: 1
  topologyKey: topology.kubernetes.io/zone
  whenUnsatisfiable: DoNotSchedule
  labelSelector:
    matchLabels:
      valkey.io/cluster: sessions
  matchLabelKeys:
  - valkey.io/shard-index

With matchLabelKeys, the constraint counts only pods of the same shard, so each shard's primary and replicas land in different zones. The labels here are the official Valkey Operator's. Other operators use different ones.

TLS and access control

Valkey supports TLS for clients, replication, and the cluster bus, and ACL users with per-command and per-key permissions. Turn both on. Valkey sits inside the cluster network, which is exactly where a compromised pod would look first. Give each application its own ACL user, keep the default user password-protected, and disable dangerous commands such as FLUSHALL, CONFIG, and DEBUG for application users. TLS adds CPU cost per connection. Valkey 8.1 moved the TLS handshake to I/O threads, which makes this much cheaper than it used to be.

3. Compute and storage strategy

Valkey's data lives in memory, so memory is where it fails. Valkey doesn't know about container limits: unless you tell it otherwise, it grows until the kernel kills it. Everything else in this section is secondary to getting that right.

maxmemory and the container limit

maxmemory is the only thing that stops Valkey from outgrowing its container, and its default is 0, meaning no limit. In our tests, a 1 GiB pod without it was OOM-killed at 1,033 MB of data. With maxmemory set and real headroom, it did exactly what the documentation says: it evicted keys or rejected writes with an OOM command not allowed error, and kept running.

The headroom matters because maxmemory counts the dataset, not everything the container uses. Forks for snapshots, buffers for replicas and clients, and allocator fragmentation all come on top. As starting points from our tests:

WorkloadmaxmemoryWhy
Cache, no persistenceAbout 80% of the memory limitNo forks. Headroom covers client buffers and fragmentation
With RDB or AOFAbout 65%Snapshots and AOF rewrites fork, and copy-on-write pages count against the container
Primary with replicasAbout 55%A full resync forks and buffers the write stream for the replica at the same time

Treat these as starting points and test under your own load. In one test, a plain BGSAVE OOM-killed two pods within a second, with hundreds of megabytes of apparent headroom, on a dataset of many small objects. Valkey 8.1 reduced fork copy-on-write overhead, and Valkey 8.0's dual-channel replication streams the snapshot and the backlog separately during a full sync, which helps. Neither replaces testing a snapshot and a full resync at your real memory usage.

resources:
  requests:
    memory: 8Gi
    cpu: "2"
  limits:
    memory: 8Gi
    cpu: "2"
config:
  maxmemory: 4400mb          # ~55% of 8Gi, primary with replicas
  maxmemory-policy: noeviction
  appendonly: "yes"
  appendfsync: everysec

Guaranteed QoS (requests equal limits)

Set requests equal to limits for CPU and memory in every container of the pod, including exporter sidecars. When a node runs low on memory, the kubelet evicts pods by how far they exceed their requests, not by how much they use. In our test, a Valkey pod with a 64 MiB request and a 4 GiB limit was evicted twice while a neighbor using four times more memory, but within its request, wasn't touched. With requests equal to limits, the neighbor was OOM-killed instead and Valkey kept running.

Eviction policies

PolicyWhen memory is fullUse for
noeviction (default)Writes fail with an OOM error. Reads keep workingData stores, where losing a key is worse than a failed write
allkeys-lru, allkeys-lfuEvicts the least recently or least frequently used keysCaches. LFU keeps popular keys better under scans
volatile-lru, volatile-lfu, volatile-ttlEvicts only keys that have a TTLMixed instances, if you must have them. Writes fail once no key with a TTL is left
allkeys-random, volatile-randomEvicts random keysRarely the right choice

Node settings: overcommit and transparent huge pages

Valkey logs two warnings at startup that are easy to ignore on Kubernetes, because the fix is on the node, not in the pod. Set vm.overcommit_memory = 1, or background saves can fail to fork on a node that looks like it has plenty of memory. And disable transparent huge pages, which make each copy-on-write fault copy 2 MB instead of 4 KB and cause latency spikes during snapshots. Neither is a namespaced sysctl, so set them in your node image or with a privileged DaemonSet on the nodes that run Valkey.

CPU

Valkey executes commands on a single main thread. Since Valkey 8.0, reading requests, writing replies, and TLS run on a pool of I/O threads set with io-threads, but each command still runs on that one thread. So a primary's throughput tops out at roughly one fully busy core plus its I/O threads, and the way to scale writes is more shards, not bigger pods. In our resharding test, every primary of a saturated three-shard cluster was pinned at one core, and doubling the shards nearly doubled throughput.

  • Give each pod at least 2 CPUs if you use I/O threads, and set io-threads to match the container's CPUs, not the node's.
  • Leave CPU for forks and AOF rewrites. They run in a child process on the same CPU limit.
  • Watch for CPU throttling. A throttled main thread shows up as p99 latency spikes long before average CPU looks high.

Persistence: none, RDB, or AOF

ModeHow it worksLost on restartCost
Nonesave "", appendonly noEverythingNo forks, no disk
RDB only (default)Periodic snapshots. The default rules save after 1 hour, 5 minutes, or 60 seconds, depending on how many keys changedEverything since the last snapshot, often a minute or moreA fork per snapshot
AOF, everysecEvery write is appended to a log, which is fsynced once a secondNothing on a process crash. Up to 1 second if the node failsAbout 6% more memory in our test, and forks for AOF rewrites
AOF, alwaysfsync on every writeNothingMuch lower write throughput, bound by disk latency

The default is the worst of both for Kubernetes: forks that can OOM-kill the pod, and a snapshot old enough to cause the persistence trap. Choose explicitly: none for caches, AOF with everysec for data stores. AOF files start with an RDB preamble and are rewritten in the background, so restarts stay fast.

Volumes

Valkey serves every read and write from memory and only writes to disk in the background, so storage latency matters much less than for a disk-based database. Network-attached volumes are fine, and they have an advantage: after a node failure, the pod comes back on another node with its data, instead of copying everything from a replica. Local NVMe helps mainly with appendfsync always.

  • Size volumes for at least two to three times maxmemory. A snapshot is written to a temporary file before it replaces the old one, and in our test the AOF was 40% larger than the data in memory.
  • Caches without persistence don't need a volume at all.
  • After scaling in a cluster, delete the PVCs of the removed shards. In our tests, leftover volumes kept an old nodes.conf, and the next scale-out mounted them and got stuck.

Fragmentation

After many deletes, the allocator keeps memory it no longer needs, and RSS stays far above used_memory. activedefrag yes fixes this in the background, but its default threshold, active-defrag-ignore-bytes of 100 MB, is sized for large servers. In our 2 GiB test pod, defragmentation stopped at a fragmentation ratio of 1.63 and looked stuck. Lowering the threshold brought it down to 1.14 in about ten seconds.

4. Monitoring Valkey on Kubernetes

Almost everything Valkey knows about itself is in the INFO command. On Kubernetes, the standard way to collect it is redis_exporter, which supports Valkey 7 through 9 and publishes INFO, cluster state, and latency data as Prometheus metrics. Run it as a sidecar in each Valkey pod with its own ACL user, and let Prometheus Operator or VictoriaMetrics find it with a PodMonitor.

apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
spec:
  selector:
    matchLabels:
      valkey.io/cluster: sessions
  podMetricsEndpoints:
  - port: metrics
    interval: 15s

For individual slow commands, use COMMANDLOG, which extends the classic slow log with commands that had unusually large requests or replies. Those are often what blocks the main thread.

Valkey-specific metrics

MetricSourceWhat to watch
Memoryused_memory, maxmemory, and used_memory_rss in INFO memory, plus the container's working setAlert at 80 to 90% of maxmemory, and separately when RSS approaches the container limit. The second is the one that ends in an OOM kill.
Evictions and rejected writesevicted_keys, and errorstat_OOM in INFO errorstatsEvictions on a data store mean data loss. OOM errors on a cache mean the eviction policy is noeviction.
Hit ratiokeyspace_hits and keyspace_missesFor caches, a falling hit ratio means the cache is too small or keys expire too soon.
Replicationmaster_link_status, the offset gap between primary and replica, and sync_fullA link that keeps going down, a growing gap, or repeated full syncs. Each full sync forks the primary.
Cluster healthcluster_state and cluster_slots_fail in CLUSTER INFOAnything other than ok means some slots aren't being served.
Persistencerdb_last_bgsave_status, aof_last_write_status, and latest_fork_usecFailed saves, and forks that take tens of milliseconds. The main thread is blocked during the fork.
Fragmentationmem_fragmentation_ratioSustained values above 1.5 waste memory. Values below 1 mean the system is swapping.

Adapting monitoring for Kubernetes

  • Alert on OOM kills from the pod status. kubectl get events never showed the word OOMKilled in our tests. Only lastState.terminated.reason in the container status did.
  • Alert when the number of keys drops sharply. A Valkey that restarted empty looks healthy to every Kubernetes check, and to most operator status fields.
  • Alert on unexpected primary changes, which point to OOM kills, evictions, or network problems.
  • Track CPU throttling for the Valkey container. It shows up as latency before it shows up as CPU usage.
  • Track PVC usage if you use AOF. A failing AOF rewrite lets the file grow until the volume fills.

5. Backup strategies

Persistence and replicas protect against crashes, not against mistakes. A FLUSHALL, a bad deploy that overwrites keys, or a deleted namespace is replicated and persisted like any other change. For a data store, you also need copies outside the cluster.

RDB snapshots to object storage

The RDB file is Valkey's natural backup format: compact, readable by the same or newer Valkey versions, and loaded automatically on startup. A backup job runs BGSAVE, waits until LASTSAVE changes and rdb_last_bgsave_status is ok, and uploads dump.rdb to S3-compatible storage. Run it on a replica, so the primary doesn't pay for the fork.

valkey-cli -h sessions-0-1 BGSAVE
# wait until LASTSAVE changes, then check INFO persistence
aws s3 cp /data/dump.rdb \
  s3://valkey-backups/sessions/shard-0/2026-11-10T0200.rdb

In Valkey Cluster, each shard is backed up separately, and the snapshots are taken at slightly different moments. There's no cluster-wide consistent point in time, so a backup restores each shard to its own snapshot. To restore, put each shard's RDB on its primary's volume before it starts, into a cluster with the same slot layout. To restore into a different number of shards, load the files with a tool that reads RDB and routes keys by slot, such as RedisShake.

Point-in-time recovery

Valkey has no point-in-time recovery. The AOF records every write, but there's no supported way to replay it up to a timestamp. Your recovery point is the age of the last snapshot, so schedule snapshots as often as you can afford to lose data, typically every 15 minutes to an hour. If you need to undo a mistake to the second, the data probably belongs in a database with a transaction log, with Valkey as a cache in front of it.

Backup architecture decisions

ApproachSetupWhy
Recommended for data storesScheduled RDB snapshots from replicas to S3 in another account or region, plus AOF on every nodeAOF covers crashes, snapshots cover mistakes and the loss of the cluster. Test restores regularly, because an untested backup is not a backup.
AcceptableCSI VolumeSnapshots of the Valkey volumesQuick to set up, but crash-consistent per pod, and the snapshots usually stay in the same storage system.
Acceptable for cachesNo backupsIf the data can be rebuilt from its source, a backup only adds cost. Plan for the load of a cold cache instead.
Not recommendedRelying on replicas or on dump.rdb on the same PVCReplicas copy mistakes immediately, and a file next to the data shares its fate.

6. Valkey operators compared

The Valkey operator landscape is young and changing quickly. The official operator is the most active, but none of the open source options is mature yet. Check which topologies each one runs, whether it handles failover itself, and whether it does backups.

OperatorMaintainerLicenseTopologiesBackups
Valkey OperatorValkey project (Linux Foundation)Apache 2.0Valkey Cluster and primary with replicas. Pre-1.0, not yet recommended for productionNot built in
OpenEverestCNCF Sandbox projectApache 2.0Valkey Cluster and primary with replicas, built on the Valkey OperatorNot yet. A control plane with a UI and API, plus Redis-to-Valkey migrations
KubeDBAppsCodeProprietaryValkey versions of its Redis resource. Check Sentinel and cluster support for ValkeyKubeStash, as for Redis
KubeBlocksApeCloudAGPL 3.0Standalone, and primary with replicas under SentinelBuilt into KubeBlocks
SAP Valkey OperatorSAPApache 2.0Primary with replicas, with optional Sentinel. No shardingNot built in
Hyperspike Valkey OperatorHyperspike (community)Apache 2.0Valkey ClusterNot built in
chideat Valkey OperatorCommunityApache 2.0Standalone, Sentinel, and clusterNot built in

Valkey Operator

The official operator, developed in the open under the Valkey project. It manages Valkey Cluster through ValkeyCluster and ValkeyNode resources and handles scaling shards and replicas with atomic slot migration, rolling upgrades that fail a primary over before restarting it, TLS and mutual TLS, ACL users, a metrics exporter, PodDisruptionBudgets, and zone-aware placement. It releases often, and its documentation is unusually honest about edge cases. It's also explicitly pre-1.0: the API can still change, upgrades sometimes need manual CRD steps, and backups aren't part of it yet. It's the operator to watch, and the one we contribute to.

KubeDB

Part of a multi-database operator suite with one management plane. Valkey runs through the same Redis resource as Redis: you pick a Valkey version instead of a Redis one, and use KubeDB's Redis tooling, including backups with KubeStash. Its Valkey documentation is still short, so confirm that the modes you need, such as Sentinel or cluster, work with Valkey versions. It isn't open source, and most features need a license. It suits teams that want one commercial operator for many databases.

KubeBlocks

An open source multi-database platform from ApeCloud. Its community Valkey add-on runs standalone instances and primary-replica setups with three Sentinel pods, with backups through KubeBlocks data protection. It doesn't run Valkey Cluster yet. KubeBlocks is AGPL-licensed, which some organizations restrict.

SAP Valkey Operator

A small operator that installs Valkey through the Bitnami Valkey Helm chart. It runs a primary with read replicas, optionally under Sentinel, with TLS, AOF, and metrics. It doesn't shard, and because it depends on the Bitnami chart, check where its images come from after Bitnami's 2025 catalog changes.

Hyperspike and chideat operators

Two community operators that predate the official one. Hyperspike's runs Valkey Cluster, but its last release was in October 2025. chideat's runs standalone, Sentinel, and cluster topologies and is actively maintained, with a small user base. Both are worth a look for specific needs, less so as a long-term default.

Helm charts and Redis operators

The Valkey project also publishes an official Helm chart. It deploys Valkey, but a chart doesn't fail over, reshard, or react to anything after installation. Most Redis operators haven't added Valkey: the OT-Container-Kit Redis operator, for example, lists it on its roadmap, and the Spotahome operator is archived.

OpenEverest

OpenEverest is a CNCF Sandbox project for running databases on Kubernetes through one control plane. Its Valkey provider is built on the official Valkey Operator. You create replicated or sharded Valkey from the same UI and API you use for PostgreSQL, MySQL, and MongoDB, with Valkey 8.1, 9.0, or 9.1, TLS on by default, optional mutual TLS, a generated password for the default user, zone-aware scheduling, and metrics for Prometheus or VictoriaMetrics. A migrations plugin moves live Redis or Valkey data into it with RedisShake. Backups aren't available yet, and like the operator underneath, the provider is pre-1.0.

OpenEverest is modular, so the operator underneath is pluggable. You learn one API and one way of operating, whichever operator or database runs underneath.

Related whitepapers

Run Valkey on Kubernetes with Solanica

Solanica builds on OpenEverest and contributes to the Valkey Operator. We help teams run Valkey on infrastructure they own, test it against the failures in this guide, and move off Redis or a managed cache without downtime. Talk to us about your setup, or try OpenEverest yourself.