If your homelab runs WordPress, Nextcloud, Grafana, GitLab, or any session-backed web application, you are almost certainly running Redis somewhere. Since Redis shifted to a non-OSI license in 2024, the community has rallied behind Valkey — a fully open-source (BSD-3-Clause), Redis-compatible fork backed by the Linux Foundation.
Valkey 9.1 dropped on May 19, 2026, and it is a significant release: 2.1 million requests per second with 512-byte payloads, database-level access control, JSON logging, and a modular Lua engine. This guide walks through deploying Valkey 9.1 with Docker Compose, configuring it for production use, hardening it with ACLs, and connecting your homelab services.
Why Valkey Over Redis
It is worth understanding the landscape. Redis was the king of in-memory key-value stores for over a decade. In 2024, Redis Ltd. switched to a Server Side Public License (SSPL), meaning you cannot offer Redis as a managed service without a commercial agreement. Valkey forked from Redis 7.2.4 under the original BSD-3-Clause license and is governed by the Linux Foundation with contributions from AWS, Google, Oracle, and Ericsson.
| Aspect | Redis | Valkey |
|---|---|---|
| License | SSPL (restrictive) | BSD-3-Clause |
| Governance | Single vendor | Linux Foundation |
| Latest stable | 7.4.x | 9.1.0 |
| Performance | Baseline | +15-25% (9.1 I/O threading) |
| DB-level ACLs | No | Yes (9.1) |
| JSON logging | No | Yes (9.1) |
| Drop-in compatible | — | Yes, same protocol and commands |
For a homelab, the practical difference is zero today — Valkey speaks the Redis protocol, so any app that connects to Redis connects to Valkey unchanged. The long-term difference is that Valkey is evolving faster and is fully open-source.
Step 1 — Docker Compose Deployment
Create a project directory and a basic docker-compose.yml:
|
|
Key points:
- Bind to 127.0.0.1: Valkey should never be exposed directly to your LAN. Only containers on the same Docker network or the host should reach it.
- Read-only config mount: Prevents runtime modification to the configuration file.
- Capability drop: Strips all kernel capabilities except the minimum needed (SETGID, SETUID, NET_BIND_SERVICE).
- Healthcheck: Every 10 seconds, Valkey-CLI pings the server.
- Separate network: Gives Valkey a predictable subnet for service discovery.
Step 2 — Valkey Configuration for Homelab
Create valkey.conf in the same directory:
# /opt/valkey/valkey.conf — Valkey 9.1 Homelab Configuration
# Bind to loopback and Docker network
bind 127.0.0.1 172.20.0.2
protected-mode yes
port 6379
# Persistence — snapshot every 5 min if at least 1 key changed
save 300 1
save 60 100
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
# Append-only file for durability (recommended for production)
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# Memory management — cap at 512MB for homelab
maxmemory 512mb
maxmemory-policy allkeys-lru
# Logging — JSON for log aggregation
logfile ""
loglevel notice
log-format json
# Lua — restrict to read-only
lua-time-limit 5000
# Performance — I/O threading (new in 9.1)
io-threads 4
io-threads-do-reads yes
# Slow log
slowlog-log-slower-than 10000
slowlog-max-len 128
# ACL — require a password
requirepass ${VALKEY_PASSWORD}
aclfile /etc/valkey/users.acl
# TLS paths (set to empty to disable)
tls-cert-file ""
tls-key-file ""
tls-ca-cert-file ""
Understanding the Memory Policy
maxmemory-policy allkeys-lru is the right choice for a homelab
caching layer. It evicts the least-recently-used key when memory
fills up. For session storage specifically, volatile-lru (evict
only keys with an expiry set) is also valid — but allkeys-lru
handles apps that forget to set TTLs.
Set maxmemory to a value that leaves enough headroom for the OS.
On a 8GB Proxmox host running several containers, 512MB is safe.
If Valkey lives on a dedicated 2GB VM, set it to 1.5GB.
Step 3 — Securing Valkey with ACLs
Valkey 9.1 introduces number database-level access control, which lets you restrict users to specific databases. This is invaluable when multiple apps share a single Valkey instance.
Create users.acl:
# /opt/valkey/users.acl
# Admin user with full access
user default on >${VALKEY_PASSWORD} ~* &* +@all
# Application users — scoped to specific databases
# WordPress — database 0
user wordpress on >wp-secure-pass ~* +@all -@dangerous db=0
# Grafana — database 1, read-mostly
user grafana on >graf-secure-pass ~* +@read +@write -@admin db=1
# Rate limiter — database 2, minimal permissions
user ratelimit on >rate-secure-pass ~* +GET +SET +EXPIRE +TTL db=2
The +@dangerous category includes FLUSHALL, FLUSHDB, DEBUG,
CONFIG, SHUTDOWN, and SLAVEOF. Removing it from application
users prevents accidental or malicious data destruction.
Load the ACL file by pointing config at it:
aclfile /etc/valkey/users.acl
Then apply it at runtime without restart:
|
|
You can test access restrictions:
|
|
Step 4 — Connecting Homelab Services
WordPress + Valkey Object Cache
Add a object-cache.php drop-in and configure wp-config.php:
|
|
Nextcloud + Valkey
Nextcloud uses Valkey for file locking, caching, and MFA rate
limiting. In config/config.php:
|
|
Grafana + Valkey
Grafana can use Valkey for session storage and query caching. In
grafana.ini:
|
|
Generic Docker Compose Service
For any other container on the same Docker network, reference Valkey by service name:
|
|
Then create the network once:
|
|
Step 5 — Verifying Performance
Valkey 9.1’s new I/O threading model and hardware-clock-based timestamps deliver measurable gains. Run the built-in benchmark:
|
|
Expect output like:
====== SET ======
100000 requests completed in 0.85 seconds
50 parallel clients
16 bytes payload
keep alive: 1
host configuration "save": 300 1
host configuration "appendonly": yes
117647.05 requests per second
====== GET ======
100000 requests completed in 0.73 seconds
50 parallel clients
16 bytes payload
keep alive: 1
host configuration "save": 300 1
host configuration "appendonly": yes
136986.30 requests per second
On a moderate homelab server (Ryzen 5, NVMe SSD), Valkey 9.1 easily hits 100k+ ops/sec. The I/O threading improvement matters most when multiple pipelines run concurrently — WordPress + Nextcloud + Grafana hitting the same instance.
Check real-time I/O thread usage:
|
|
Step 6 — Monitoring with JSON Logging
New in 9.1: Valkey can emit logs in JSON format, making them natively parseable by Loki, OpenSearch, or any JSON-aware log shipper.
With log-format json enabled, logs look like:
|
|
If you have Grafana Alloy or Promtail collecting Docker logs, they will pick up the JSON format automatically with zero parsing configuration — no regex-based log scraping needed.
Step 7 — Backups and Maintenance
Valkey persists to both RDB snapshots and AOF logs. Back them up:
|
|
Or trigger BGSAVE and copy the file zero-downtime:
|
|
For zero-data-loss scenarios, enable AOF with appendfsync everysec. You lose at most one second of writes on a crash.
When to Skip Valkey
Valkey is not always the right tool:
- Ephemeral caching only: If you never need the data across
restarts, run Valkey with
save ""andappendonly no. It becomes a pure cache with no disk writes. - Single-app homelab: If you have one small app, a SQLite file or a Docker volume-mounted JSON file is simpler.
- High memory pressure: Valkey stores everything in RAM. If your homelab runs on a 4GB NUC with existing services, add memory before reaching for Valkey.
For everything else — session storage, API rate limiting, job queues, real-time dashboards, object caching — Valkey 9.1 is the best open-source option available today.
Summary
Valkey 9.1 brings database-level ACLs, JSON logging, I/O threading, and significant performance improvements to the Redis-compatible ecosystem. Switching from Redis to Valkey is a drop-in replacement — export your RDB, change the image tag, and restart. No code changes.
Beyond the migration story, the new security and observability features make Valkey 9.1 a genuinely better choice for any homelab running multiple applications. Database-scoped users mean you can safely share one Valkey instance across WordPress, Grafana, Nextcloud, and a custom rate-limiter without worrying about cross-tenant data access.
Deploy it today, set up ACLs, point your apps at it, and forget about it. That is the Valkey way.