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.
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) and6380(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 primary6380— read/write over TLS, routed to the current primary7000— read-only (non-TLS), load-balanced across replicas7001— 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.
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.
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.
| Variable | Example value | Notes |
|---|---|---|
hostname | db | Service hostname; reachable as db.zerops inside the project |
port | 6379 | Plain (non-TLS) port |
portTls | 6380 | TLS port |
password | (generated) | Password for the default user (sensitive) |
connectionString | redis://default:<password>@db.zerops:6379 | Ready-to-use non-TLS URL |
connectionTlsString | rediss://default:<password>@db.zerops:6380 | Ready-to-use TLS URL |
In HA mode four additional variables expose the read-only replica endpoints (load-balanced across replicas):
| Variable | Example value | Notes |
|---|---|---|
portReplicas | 7000 | Read-only plain port |
portTlsReplicas | 7001 | Read-only TLS port |
connectionStringReplicas | redis://default:<password>@db.zerops:7000 | Read-only non-TLS URL |
connectionTlsStringReplicas | rediss://default:<password>@db.zerops:7001 | Read-only TLS URL |
The connection string format is redis://default:<password>@<hostname>.zerops:<port> (or rediss:// for TLS). The username is always default.
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:
If your client has no equivalent option, run your own heartbeat on every long-lived connection:
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.
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.
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%.
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 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.
| Value | Behavior | When to use |
|---|---|---|
noeviction | Reject writes with an OOM error | Datasets where every key must be preserved (session storage without TTL, job queues). Requires careful capacity planning. |
allkeys-lru | Evict least-recently-used keys | General-purpose caching — the safe default |
allkeys-lfu | Evict least-frequently-used keys | Hot/cold workloads where access frequency matters more than recency |
allkeys-random | Evict random keys | Uniform access patterns (rare) |
volatile-lru | Evict LRU keys with a TTL set | Mixed workloads: persistent keys without TTL are protected, cache keys with TTL are evictable |
volatile-lfu | Evict LFU keys with a TTL | Same as volatile-lru, frequency-based |
volatile-random | Evict random keys with a TTL | Rarely appropriate |
volatile-ttl | Evict keys with the shortest remaining TTL | When TTL reflects priority |
noeviction and memory pressureWith 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
- Official Valkey Documentation - Comprehensive guide to Valkey features
Support
For advanced configurations or custom requirements:
- Join our Discord community
- Contact support via email