Keycloak 26.7 Stateless Mode: Multi-Region Without Infinispan

Guilliano Molaire Guilliano Molaire 9 min read
Global DNS diagram: three Keycloak instances connected to a single distributed SQL cluster.

Last updated: July 2026

Keycloak 26.7 ships multi-cluster v2, a preview architecture built around a new stateless feature: two or more fully independent Keycloak clusters, one synchronously replicated database holding every piece of shared state, and no external Infinispan anywhere. Embedded Infinispan shrinks to local caches only, and cross-cluster cache invalidation runs through a database outbox table. The catch is a hard sub-10 ms latency requirement between clusters, which makes this metro-scale multi-region, not intercontinental. We’ve already started testing it against YugabyteDB, and this post covers the architecture we’re exploring plus what our first PoC round found.

This is part 1 of a two-part series. Today is the theory: what actually changed in 26.7, the three-layer multi-cloud design we’re sketching, and the single-region groundwork we’ve already run. Part 2, next week, takes the full multi-cloud, multi-region test end to end. If you’re newer to Keycloak, start with our complete guide to Keycloak and come back. This one assumes you’ve run it in production before.

What is the stateless feature in Keycloak 26.7?

stateless is the feature flag behind multi-cluster v2, a preview architecture in Keycloak 26.7 for running two or more independent Keycloak clusters against a single database. All shared state (users, realms, clients, and sessions) lives in one synchronously replicated database. Each cluster keeps its embedded Infinispan strictly for local caching, nothing crosses cluster boundaries except database traffic.

That’s a bigger shift than it sounds. The previous multi-site architecture depended on an external Infinispan cluster stretched between sites, and its blueprints were tied to specific environments. The new docs are explicit that v2 removes the external Infinispan requirement and “lifts any requirement for a specific environment such as Kubernetes or AWS”. Any two clusters that can reach the same database qualify, on any infrastructure.

The Keycloak team has load-tested the architecture at 1,000,000 users and 300 requests per second, and they’re collecting feedback in GitHub discussion #50640. It’s still a preview feature though. Treat it as something to test aggressively, not something to bet your production login flow on this quarter. The release line has moved fast since Keycloak 25, and this is the most interesting architectural change in it.

How is multi-cluster v2 different from the old multi-site setup?

The short version: v1 made Infinispan do the cross-site work, v2 makes the database do it. Everything else follows from that swap.

Multi-site (v1) Multi-cluster v2 (stateless)
External Infinispan Required, stretched across sites Not used at all
Shared state Split between database and remote caches One synchronously replicated database
Environment Blueprints tied to Kubernetes and AWS Any environment
Topology Two sites Two or more independent clusters
Cache invalidation Infinispan cross-site replication Database outbox table
Distributed systems you operate Keycloak, database, and Infinispan Keycloak and database

The stretched Infinispan was the hardest part of v1 to live with. It was a second distributed system to size, secure, monitor, and upgrade, with its own failure modes layered on top of Keycloak’s. v2 deletes that entire layer.

The honest flip side: the docs state plainly that stateless “increases database load compared to setups with an external Infinispan cluster”. You traded a cache cluster for a heavier, more critical database. Whether that’s a good trade depends entirely on what database you put underneath, which is where our exploration starts.

Multi-site v1 with external Infinispan versus multi-cluster v2 stateless where the database does the work

How do caches stay consistent without Infinispan?

Through an outbox pattern in the database. When one cluster changes data that other clusters may have cached, it writes an invalidation message to a queuing table. Every cluster polls that table on an interval, 100 ms by default, and evicts the matching entries from its local caches.

There are three more numbers worth knowing. After writing an invalidation, the sending cluster waits five times the polling interval (500 ms at defaults) to give every other cluster time to consume the message. Messages are retained in the table for 60 seconds. And as the backstop, cached entries expire after 1 hour regardless, so even a missed invalidation produces bounded staleness rather than a permanently wrong cache.

The visible cost is on writes to shared configuration: the docs call out that realm-data updates are slower than in a single-cluster deployment because of this propagation dance. In our reading, that’s the right trade for an identity system. Admin config changes are rare and can afford half a second; logins are constant and can’t.

The three-layer architecture we’re exploring

What we’re chasing is something we’ve been calling super-available Keycloak: three independently redundant layers, each one able to lose a member without the system losing correctness. No single cloud, single cluster, single database node, or single DNS answer is load-bearing on its own.

Three-layer super-available Keycloak architecture: global DNS, independent Kubernetes clusters per cloud, one distributed SQL database

Layer 1: global DNS and traffic steering

The top layer is a global load balancer (Route 53 or Cloudflare Load Balancing) doing latency-based routing with health checks against each cluster’s /lb-check endpoint. Multi-cluster v2 is designed for exactly this: a standard load balancer probing a standard health endpoint, no Keycloak-aware routing logic. When a cluster degrades, health checks fail and DNS steers users to the remaining healthy clusters within seconds.

Layer 2: independent Kubernetes clusters, one per cloud

The middle layer is where the stateless feature earns its name. In our target diagram, that’s three independent Kubernetes clusters, one each on AWS, Azure, and GCP, each running 3 Keycloak 26.7 pods with stateless enabled. There’s no cross-cluster mesh, no stretched Kubernetes, no shared cache fabric. Each cluster carries a unique cluster name and knows nothing about its siblings.

Losing an entire cloud loses capacity, not correctness. The surviving clusters keep answering logins from the same database while DNS drains traffic toward them. Each cluster still gets sized the normal way, by request rate using the official formula we break down in our Keycloak sizing guide.

Layer 3: one distributed SQL database

The bottom layer does the heavy lifting, because in v2 the database is the entire shared-state story. Two candidates fit the synchronous-replication requirement: YugabyteDB with RF=3, where every tablet runs its own Raft group and commits synchronously across three nodes (that’s what we’re testing), and Amazon Aurora DSQL as the managed multi-region active-active alternative.

Let’s be honest about what this layer really is: it’s where the CAP trade-off now lives. The old architecture spread that tension across Infinispan and the database. v2 concentrates it in one place, which is cleaner to reason about but means the database is the single critical path and deserves every bit of the operational care Infinispan used to demand.

What we found running Keycloak 26.7 on YugabyteDB

We didn’t want to publish an architecture diagram we hadn’t started proving, so we already began testing. We built a proof of concept that runs Keycloak against a distributed SQL cluster, and the results were better than we expected. We plan to share the full methodology alongside part 2.

All 10 Keycloak version hops from 25.0.0 through 26.7.0 ran, migrated, and benchmarked cleanly against a 3-node RF=3 YugabyteDB cluster. Liquibase migrated hop-by-hop against the same persistent database, exactly like a real upgrade history would. We benchmarked each hop with the official keycloak-benchmark tool on the client-credentials grant in a July 2026 run: 0% errors on every hop, and roughly 15-45 ms p95 across every 26.x hop. A distributed SQL database surviving ten consecutive Keycloak schema migrations without a single manual fix is the boring result you want.

Then there’s the naming gotcha we hit so you don’t have to. The cacheless multi-cluster v2 flag is stateless, not clusterless. The misleadingly named clusterless flag and the older multi-site flag both hard-require cache-remote-host, meaning an external Infinispan, and refuse to start without one. This is the combination that boots healthy on 26.7.0 with zero Infinispan anywhere:

bin/kc.sh start 
  --features=persistent-user-sessions,stateless 
  --db=postgres 
  --db-url=jdbc:postgresql://<yugabyte-endpoint>:5433/keycloak

YugabyteDB speaks the PostgreSQL wire protocol on port 5433, so Keycloak’s stock postgres driver connects unmodified. We also went one step further and probed YugabyteDB’s JDBC smart driver, via a custom --db-driver build with load-balance and topology-keys enabled, to get per-node connection distribution across a simulated aws/azure/gcp metro quorum. That’s the connection layer the three-cloud diagram will need. If you want a local Keycloak to poke at these flags yourself, our Docker Compose generator will hand you a runnable stack in about a minute.

How far apart can the clusters actually be?

This is the part most coverage of 26.7 will gloss over, and it deserves its own section. The docs suggest round-trip latency below 5 ms and require it below 10 ms, both within and between clusters. That single number defines the whole shape of what you can build.

Synchronous replication has physics, not opinions. You cannot commit a transaction synchronously across an ocean and also answer logins in single-digit milliseconds; a transatlantic round trip alone burns many multiples of the entire latency budget. So multi-cluster v2 is metro-scale multi-cluster: nearby regions, and different clouds whose datacenters happen to sit in the same metro. Northern Virginia is the canonical example, where AWS, Azure, and GCP all operate within a short fiber run of each other. That’s genuinely valuable (whole-cloud failure independence with active-active correctness), but it is not global active-active.

Truly global topologies remain follower-reads and geo-partitioning territory, where reads go local and writes accept their round trip. That’s precisely the experiment we’ve queued for part 2.

What you need before trying stateless mode

Before you point a test deployment at three clouds, here’s the checklist the docs actually impose:

  • Round-trip latency below 10 ms required, below 5 ms suggested, within and between clusters
  • A synchronously replicated database, no async read replicas standing in for it
  • A standard load balancer or DNS layer probing /lb-check on each cluster
  • Sticky sessions disabled at the ingress
  • Monitoring that catches degraded setups, because the failure guarantees only hold from a non-degraded state

On Kubernetes, the deployment specifics matter. Enable the feature in the Keycloak CR, give every cluster a unique embedded-cache cluster name, verify database TLS, and keep pool sizes identical across clusters:

apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
spec:
  features:
    enabled:
      - stateless
  db:
    poolMinSize: 30
    poolInitialSize: 30
    poolMaxSize: 30
  additionalOptions:
    - name: spi-cache-embedded--default--cluster-name
      value: cluster-aws-use1   # must be unique per cluster
    - name: db-tls-mode
      value: verify-server

The failure model is strong on paper: no data loss (RPO of zero) and recovery in seconds to minutes for node failures, database-node failures, connectivity loss, and whole-site failures. The fine print: those guarantees apply only when you start from a healthy, non-degraded state, failure detection itself takes about a minute, and some database failure scenarios still need vendor-specific manual intervention. Monitoring isn’t garnish here, it’s a structural component. And while you’re hardening, most of the 8 default configurations we always adjust on Keycloak clusters still apply to every individual cluster in this topology.

Where part 2 goes

Part 1 was the theory plus the groundwork: 26.7’s stateless flag boots clean with no Infinispan, and YugabyteDB carries ten consecutive Keycloak versions with 0% benchmark errors. Part 2, next week, runs the real thing end to end: three Kubernetes clusters across AWS, Azure, and GCP metro regions, global DNS steering, kill-a-cloud failure drills against /lb-check, and the follower-read experiments that hint at what global could eventually look like.

One honest sentence to close: this is the architecture direction we’re exploring for our managed Keycloak platform, not a shipped product. When it graduates from preview and from our test benches, you’ll read about it here first.

Frequently asked questions

Does Keycloak support multi-region active-active deployments?

Yes, within limits. Keycloak 26.7’s multi-cluster v2 preview runs two or more independent clusters active-active against one synchronously replicated database. The required sub-10 ms round-trip latency between clusters restricts it to metro-scale distances: nearby regions or co-located clouds, not intercontinental pairs.

What is the stateless feature in Keycloak 26.7?

stateless is a preview feature flag that moves all shared state (users, realms, clients, and sessions) into the database and demotes embedded Infinispan to purely local caching. It’s the foundation of the multi-cluster v2 architecture, works in any environment, and handles cross-cluster cache invalidation through a database outbox table polled every 100 ms.

Does Keycloak still need an external Infinispan for multi-site?

The older multi-site (v1) architecture still requires one, and both the multi-site and clusterless feature flags refuse to start without cache-remote-host. Multi-cluster v2 with the stateless flag removes the external Infinispan entirely and hands its job to the synchronously replicated database.

Can Keycloak run on YugabyteDB?

Yes. YugabyteDB’s YSQL layer speaks the PostgreSQL wire protocol, so Keycloak connects with its standard postgres driver. In our PoC, all 10 versions from 25.0.0 through 26.7.0 migrated hop-by-hop and benchmarked at 0% errors with roughly 15-45 ms p95 on a 3-node RF=3 cluster. It’s not on Keycloak’s officially supported database list, so treat it as experimental for now.

What network latency does Keycloak multi-cluster v2 require?

Round-trip latency below 10 ms is required, and below 5 ms is suggested, both within a cluster and between clusters. The same budget effectively applies to the database’s synchronous replication path. In practice that limits deployments to metro-area distances.

Tired of running Keycloak yourself?

Skycloak runs real upstream Keycloak for you with a 99.99% SLA. No fork, no lock-in, just managed Keycloak that stays patched and on call so you don't have to.

Guilliano Molaire
Written by
Founder

Guilliano is the founder of Skycloak and a cloud infrastructure specialist with deep expertise in product development and scaling SaaS products. He discovered Keycloak while consulting on enterprise IAM and built Skycloak to make managed Keycloak accessible to teams of every size.

Start Free Trial Talk to Sales
© 2026 Skycloak. All Rights Reserved. Design by Yasser Soliman