Skip to main content
Skip to main content

Valkey

Valkey is a powerful, open-source alternative to Redis, offering full compatibility with Redis clients while providing an independent development path focused on community-driven innovation. Deploy and manage Valkey in Zerops' fully managed infrastructure to get instant access to high-performance in-memory data storage.

Tip

Valkey is our recommended Redis alternative as KeyDB's development has slowed significantly in recent times.

Supported Versions

Currently supported Valkey versions:

  • 7.2

Import configuration version:

  • valkey@7.2

Service Configuration

Zerops offers Valkey in two deployment configurations to meet different availability requirements.

Single Setup

  • Single node deployment on port 6379 (non-TLS) and 6380 (TLS)
  • Suitable for development or non-critical workloads

See Persistence for how data is stored and recovered.

HA (High Availability) Setup

The HA deployment is a 3-node cluster with automatic failover, fronted by an HAProxy load balancer on every node.

  • 3-node configuration: 1 primary + 2 replicas
  • Client-facing ports (available on every node):
    • 6379 — read/write (non-TLS), routed to the current primary
    • 6380 — read/write over TLS, routed to the current primary
    • 7000 — read-only (non-TLS), load-balanced across replicas
    • 7001 — read-only over TLS, load-balanced across replicas
  • Failover is handled by a built-in Sentinel cluster. When the primary becomes unreachable, a replica is promoted automatically and HAProxy starts routing writes to it.
  • TLS is terminated at HAProxy.
  • Connect your application to the standard ports — the address never changes when the primary moves.
Note

Replica reads (ports 7000/7001) can lag slightly behind the primary due to asynchronous replication.

Failover client impact: expect roughly 10–15 seconds of write unavailability while a new primary is elected and HAProxy reconverges. Read traffic on surviving replicas is unaffected.

Trusting the TLS certificate

The certificates served on the TLS ports (6380 and 7001) are signed by the Zerops Certificate Authority. To verify them from outside Zerops, download and trust the Zerops CA — e.g. redis-cli --tls --cacert ./zerops-ca.pem -h <ip> -p 6380 -a <password>.

Connecting

Zerops generates the connection details as environment variables on the Valkey service. Reference them from another service in the same project as ${<hostname>_<variable>} — for a service named db, the connection string is ${db_connectionString}. The examples below assume the hostname db.

VariableExample valueNotes
hostnamedbService hostname; reachable as db.zerops inside the project
port6379Plain (non-TLS) port
portTls6380TLS port
password(generated)Password for the default user (sensitive)
connectionStringredis://default:<password>@db.zerops:6379Ready-to-use non-TLS URL
connectionTlsStringrediss://default:<password>@db.zerops:6380Ready-to-use TLS URL

In HA mode four additional variables expose the read-only replica endpoints (load-balanced across replicas):

VariableExample valueNotes
portReplicas7000Read-only plain port
portTlsReplicas7001Read-only TLS port
connectionStringReplicasredis://default:<password>@db.zerops:7000Read-only non-TLS URL
connectionTlsStringReplicasrediss://default:<password>@db.zerops:7001Read-only TLS URL

The connection string format is redis://default:<password>@<hostname>.zerops:<port> (or rediss:// for TLS). The username is always default.

Authentication

Valkey requires a password. It is generated automatically, exposed as the sensitive ${db_password} variable, and already embedded in the connectionString variables above. Connect with it directly — e.g. redis-cli -h db.zerops -p 6379 -a "$db_password".

Services created without a password variable (older deployments) keep working without authentication and are unaffected. All deployments created since this release require the password.

Idle connection timeout

Valkey closes connections that stay idle for 5 minutes (timeout 300). This is intentional on the managed instances — we avoid keeping infinite idle connections open. Older Valkey services ran with no timeout (timeout 0); if you connected before this change, your connections used to stay open indefinitely.

"Idle" means no commands sent on the connection — the server resets the timer on every command, so a busy connection is never closed. The connections most likely to be affected are long-lived ones that sit waiting rather than sending commands, typically pub/sub subscribers and blocking reads (BLPOP, XREAD, …). Most clients reconnect automatically, so you may only see log lines such as Redis subscriber socket closed; reconnecting if possible. — but the reconnect churn can drop pub/sub messages published in the gap.

To keep idle connections open, send an application-level PING on an interval shorter than 300s. A TCP keep-alive alone is not enough — keepalive packets live below the application layer and don't count as Valkey commands, so they don't reset the idle timer.

Many clients have a built-in option for this. For example, node-redis:

const redisClient = createClient({
url: redisURL,
pingInterval: 10000, // send PING every 10s; keeps the connection under the 300s idle limit
});

If your client has no equivalent option, run your own heartbeat on every long-lived connection:

const heartbeat = setInterval(() => {
publisher.ping().catch(() => {});
subscriber.ping().catch(() => {});
}, 60000); // any interval under 300s

For ordinary request/response traffic, a connection pool that recycles connections handles this transparently.

Persistence

Valkey persists data to disk with AOF (append-only file), so the dataset survives restarts and is rebuilt automatically on startup.

  • AOF is enabled (appendonly yes) and synced to disk every second (appendfsync everysec). After an unclean crash you lose at most ~1 second of the most recent writes.
  • RDB snapshots are disabled (save "") — durability relies on AOF, not periodic snapshots.

Durability by mode:

  • Single: the AOF lives on the node's local disk. Data survives service restarts but is lost if the underlying hardware node fails and no backup exists.
  • HA: writes are additionally replicated to two replicas, so the dataset survives the loss of any single node via automatic failover.
Backups

Platform-managed encrypted backups are available for both Single and HA setups. They are disabled by default — enable them on the service if you need point-in-time recovery beyond AOF and replication.

Memory and Autoscaling

You don't set maxmemory directly. Zerops sizes it at 80% of the container's available RAM — precisely 80% of the smaller of your configured maximum RAM and the cgroup-allocated RAM. It is re-evaluated and adjusted automatically about every 30 seconds, so maxmemory tracks the container as it scales vertically. The remaining 20% covers Valkey's internal overhead (fork on AOF rewrite / replica sync, fragmentation) and the OS.

Keep minimum free RAM above 20% when customizing autoscaling

If you edit the autoscaling configuration, keep the minimum free RAM above 20%. Zerops caps maxmemory at 80% of available RAM, so the dataset alone can never push free RAM below 20%. If your minimum free RAM threshold is at or below 20%, the scale-up trigger may never fire at all — free RAM never crosses it, so the service stays stuck at its current size and starts evicting keys (or rejecting writes under noeviction) instead of scaling up. Setting the threshold above 20% lets the dataset's growth toward the 80% cap cross the trigger, so the service scales up in time and keeps headroom for the fork during an AOF rewrite or replica sync. The built-in profiles all keep this threshold above 20%.

Check the logs for OOM events

Watch the service's runtime logs for out-of-memory events — typically the kernel OOM-killer terminating and restarting Valkey when a fork during an AOF rewrite or replica sync briefly inflates memory. Recurring OOMs mean the reserved headroom isn't enough for your workload's peaks. Raise the minimum free RAM (more headroom) or the minimum RAM (a higher floor) until they stop.

Tunable Parameters

The maxmemory-policy Valkey setting is exposed as an autoscaling profile override. In the GUI, open the service's Automatic scaling configuration, click Adjust scaling and set them under Overrides. Zerops applies the change live — no service restart, no client reconnect. In HA mode the change is rolled out to every node.

To set the parameters at creation time, use profileOverrides in your import YAML (a profile must be selected to use overrides — available profiles are hobby, staging and production):

services:
- hostname: redis
type: valkey:ha@7.2
profile: staging
profileOverrides:
maxmemory-policy: noeviction
Migrating from environment variables

Services created before profile overrides existed configure this setting via the VALKEY_MAXMEMORY_POLICY environment variable. It keeps working, but once a profile override is set it takes precedence over the environment variable.

maxmemory-policy

Default: allkeys-lru. Controls what Valkey does when the dataset reaches maxmemory.

ValueBehaviorWhen to use
noevictionReject writes with an OOM errorDatasets where every key must be preserved (session storage without TTL, job queues). Requires careful capacity planning.
allkeys-lruEvict least-recently-used keysGeneral-purpose caching — the safe default
allkeys-lfuEvict least-frequently-used keysHot/cold workloads where access frequency matters more than recency
allkeys-randomEvict random keysUniform access patterns (rare)
volatile-lruEvict LRU keys with a TTL setMixed workloads: persistent keys without TTL are protected, cache keys with TTL are evictable
volatile-lfuEvict LFU keys with a TTLSame as volatile-lru, frequency-based
volatile-randomEvict random keys with a TTLRarely appropriate
volatile-ttlEvict keys with the shortest remaining TTLWhen TTL reflects priority
noeviction and memory pressure

With noeviction, Valkey cannot free memory on its own — once the dataset reaches maxmemory, writes fail with OOM errors until the service scales up or keys are deleted. Make sure your autoscaling limits (maximum RAM) leave enough room for the dataset's growth.

Metrics

Prometheus-compatible metrics are exported by default for scraping, on the port given by the ZEROPS_PROMETHEUS_PORT variable (db:9121).

Learn More

Support

For advanced configurations or custom requirements: