Keycloak on Redis. Without the JGroups tax.
Locke is a drop-in Keycloak distribution that runs Keycloak's caching on Redis instead of an embedded JGroups cluster. Same admin console, same database, one switch (KC_CACHE=redis).
What is Locke
Stock Keycloak, with a Redis cache backend.
Locke is the upstream Keycloak codebase plus one thing: a Redis cache backend behind a single switch. Same SPIs, same admin console, same database schema. Flip it back and you have ordinary Keycloak.
Drop-in
Flip KC_CACHE=infinispan|redis at boot. No code changes, no migration.
Apache 2.0
Fully open source: stock Keycloak plus a Redis cache backend, nothing locked away.
Bring your own Redis
Works with any managed Redis. Colocated or external performs the same.
No JGroups to operate
No cluster discovery, split-brain handling, or state transfer. Redis coordinates.
The benchmark
Same throughput. Dramatically better failure behavior.
A 3-instance production cluster, head to head. Throughput is a tie. The difference shows up the moment a node dies.
| Load (logins/sec) | Stock / Infinispan | Locke / Redis | Parity |
|---|---|---|---|
| 80 | 274 req/s | 274 req/s | 100% |
| 160 | 548 req/s | 548 req/s | 100% |
| 250 | 856 req/s | 856 req/s | 100% |
p99 login latency when a node is lost (lower is better)
Bars use a compressed scale to keep Locke visible; the gap is ~15-34x. When an Infinispan node dies, the cluster stalls on a JGroups rebalance and state transfer. Locke keeps serving from Redis.
3-instance cluster, Keycloak 26.6.1, start --optimized, keycloak-benchmark Gatling AuthorizationCode flow. Full methodology in the report.
Why it matters
Built for the operators on call.
Resilience
A lost node is a sub-second blip, not a 31-second JGroups rebalance stall that hangs authentication mid-incident.
Upgrades
Across an Infinispan-version boundary the recommended Keycloak path is a brief planned restart; Locke can do that same upgrade as a rolling update because there is no JGroups version handshake. Keycloak doesn't guarantee no-downtime minor upgrades in general, so this is one fewer constraint, not a blanket promise.
Operations
Point Keycloak at the managed Redis you already run and monitor. No JGroups discovery, no state transfer, one less distributed system to operate.
Quick start
One image. One switch.
Run the Locke image in production mode and point it at your Redis.
docker run ghcr.io/sky-cloak/locke:latest start --optimized
# Switch the cache backend to Redis
KC_CACHE=redis
KC_CACHE_REDIS_URL=redis://your-redis:6379
The honest part
An honest trade. Moving local caches to Redis adds a few milliseconds of read latency at moderate load (both stay under 170ms p99 to 250 logins/sec). And Redis does not raise Keycloak's realm-count ceiling. That limit is database-bound, not cache-bound. We benchmark these things and say so.
Run Keycloak on the cache you already operate.
Open source, Apache 2.0, benchmarked in production mode.