Sticky Sessions vs. Stateless Clustering in Keycloak
The complete, in-depth guide to two very different ways of keeping a multi-node Keycloak deployment working reliably under load.
Imagine a busy hospital reception desk staffed by several receptionists working side by side. One approach is to have each patient always return to the exact same receptionist for every visit, since that receptionist personally remembers their file and history without needing to ask anyone else. Another approach is to keep every patient’s file in a shared central cabinet that any receptionist can pull from instantly, so a patient can walk up to whichever desk happens to be free and still be helped exactly as well. Running Keycloak across more than one server, called a cluster, faces this exact same choice, and the two approaches have real names: Sticky Sessions and Stateless Clustering.
This guide is a comprehensive, ground-up exploration of both approaches: what a session actually is and why it matters at all, how a load balancer’s routing decision changes everything downstream, the internal caching technology Keycloak relies on either way, the genuine trade-offs each approach makes around failover, scalability, and operational complexity, and the real-world reasoning that leads different organizations to different choices. No prior background with clustering or load balancing is assumed — every term is explained in full the moment it first appears.
1Core Concepts
Why Run More Than One Keycloak Server?
A single Keycloak server, like any single piece of infrastructure, represents both a capacity limit and a single point of failure. Running several Keycloak instances together as a cluster lets an organization handle more simultaneous logins than one server could alone, and keeps authentication working even if one particular server instance goes down.
What Is a Session, in This Context?
When a user logs in, Keycloak creates a session — a piece of server-side state remembering that this user is currently authenticated, along with details needed to support things like Single Sign-On across multiple applications and eventual logout. The genuinely hard question a cluster has to answer is: when this same user makes their next request, and it happens to land on a different server than the one that created their session, how does that second server know the session even exists?
Sticky Sessions and Stateless Clustering aren’t competing technologies solving different problems — they’re two different answers to this exact same question. One avoids the question by making sure a user’s requests always land on the same server that already has their session. The other answers it directly, by making sure every server can see every session no matter where it was created.
2Architecture & Components
graph TD
User["User's Browser"]
LB["Load Balancer"]
Node1["Keycloak Node 1"]
Node2["Keycloak Node 2"]
Node3["Keycloak Node 3"]
Cache["Infinispan
Session Cache"]
User --> LB
LB --> Node1
LB --> Node2
LB --> Node3
Node1 Cache
Node2 Cache
Node3 Cache
Load Balancer
The component deciding which specific Keycloak Node handles each incoming request — its routing decision is where the entire Sticky-vs-Stateless distinction actually lives.
Keycloak Nodes
Individual running Keycloak server instances, each capable of handling authentication requests.
Infinispan
Keycloak’s built-in, embedded caching technology, used to actually hold session data and, depending on configuration, share it across Nodes — covered fully in Chapter 5.
Session Affinity Setting
The Load Balancer’s own configuration determining whether it always sends a given user back to the same Node (Sticky Sessions) or routes freely (Stateless Clustering).
3Deep Dive: Sticky Sessions
How It Works
With Sticky Sessions (also called session affinity), the Load Balancer is configured to remember which specific Node handled a given user’s very first request, and to route every subsequent request from that same user back to that exact same Node, for as long as their session remains active.
How the Load Balancer Remembers
This is commonly achieved through a cookie the Load Balancer itself sets, identifying which Node originally handled the request, or by examining a routing identifier already embedded in Keycloak’s own session cookie. Either way, the Load Balancer consults this marker on every incoming request and directs traffic accordingly.
This is the hospital patient always returning to the same receptionist from the opening. The receptionist genuinely does hold that patient’s file locally and doesn’t need to ask anyone else — fast and simple, for as long as that one receptionist is actually at their desk and available.
The Genuine Appeal of This Approach
Because the Node handling a request already has the relevant session data close at hand, Sticky Sessions can avoid some of the network overhead and complexity involved in constantly synchronizing session data across every Node in a cluster — a real, tangible benefit that explains why this remains a common, practical starting point for many deployments.
A Reasonable Default for Traditional, Long-Lived Infrastructure
In an environment where individual servers are provisioned deliberately, run for extended periods without being casually replaced, and are only taken down for planned, well-communicated maintenance windows, the specific weakness covered in the next chapter is a genuinely rarer event to actually encounter in practice — which is part of why Sticky Sessions has historically been such a common, comfortable default in more traditional, non-containerized infrastructure setups.
4Deep Dive: The Failover Problem With Sticky Sessions
What Happens When the Assigned Node Fails
If the specific Node a user has been “stuck” to crashes, is taken down for maintenance, or otherwise becomes unavailable, the Load Balancer has no choice but to route that user’s next request somewhere else. If that new Node has no way to see the original session data, the user’s session is effectively lost — from their perspective, they’ve been abruptly, unexpectedly logged out.
This is the central, unavoidable tension covered throughout this guide: Sticky Sessions’ simplicity comes at the direct cost of resilience against a single Node’s failure, unless it’s paired with some additional mechanism to actually replicate session data — which, as covered in the next chapter, tends to blur the line between the two approaches this guide is comparing.
Production Example: A Routine Deployment Causing Unexpected Logouts
An organization performing a routine rolling deployment — taking one Node down at a time to update it — using pure Sticky Sessions without any session replication underneath, would see every user currently stuck to that specific Node abruptly lose their session the moment it goes down for the update, even though the deployment itself was planned and entirely routine.
Why This Surprises Teams Who Tested Only the Happy Path
A deployment relying on pure Sticky Sessions can pass every ordinary functional test with flying colors, since those tests rarely simulate an actual Node disappearing mid-session. This particular failure mode tends to surface only once real production traffic meets a real, unplanned (or even routinely planned) Node outage — precisely the moment when a team least wants to be discovering a gap in their own architecture for the first time, which is exactly why the deliberate failover testing recommended in Chapter 14 matters so much more here than in a simpler, single-server deployment, and why it deserves a place in a team’s regular operational routine rather than being treated as a one-time, pre-launch checkbox.
5Deep Dive: Infinispan and Session Replication
What Infinispan Is
Infinispan is an open-source, distributed caching technology that Keycloak embeds internally to store session data, among other things. “Distributed” here means Infinispan is specifically designed to hold data that’s replicated or shared across multiple running instances, rather than living in only one place.
How Infinispan Enables Session Sharing Across Nodes
When Keycloak’s Nodes are configured to form an Infinispan cluster together, a session created on one Node is replicated to the others (or made discoverable across them, depending on the specific replication strategy configured), meaning a request landing on a different Node than the one that created a given session can still find and use that session’s data.
This is the shared central filing cabinet from the opening. Every receptionist can pull the exact same patient file, regardless of which desk that patient happens to walk up to, because the file itself lives somewhere all of them can reach — not locked inside any one receptionist’s own desk drawer.
It’s worth being precise here: Infinispan isn’t exclusive to Stateless Clustering. Even a Sticky Sessions deployment typically still uses Infinispan internally for other purposes. The real distinction covered in this guide is whether the deployment actually relies on Infinispan’s cross-Node replication to survive a Node failure gracefully, or whether it leans on the Load Balancer’s routing consistency instead and treats replication as a secondary safety net, if configured at all.
6Deep Dive: Stateless Clustering
How It Works
Under Stateless Clustering, the Load Balancer makes no attempt to route a given user consistently to the same Node — any Node can handle any request from any user at any time. This works because every Node relies on Infinispan’s replication to access the same, consistent session data, regardless of which Node originally created it.
Why “Stateless” Can Be a Slightly Misleading Name
The name doesn’t mean Keycloak itself has no session state at all — it very much still does. It means the Load Balancer’s routing decision doesn’t need to depend on that state, since every Node is equally capable of retrieving it from the shared, replicated cache. The “statelessness” describes the Load Balancer’s own routing logic, not Keycloak’s actual session data.
Production Example: Surviving a Node Failure Without Any User Impact
Under a properly configured Stateless Clustering setup, if one Node crashes, the Load Balancer simply routes affected users’ subsequent requests to any of the remaining, healthy Nodes, each of which can retrieve the exact same session data from the shared Infinispan cache — the user experiences no interruption at all, unaware anything even happened behind the scenes.
7Side-by-Side Comparison
| Dimension | Sticky Sessions | Stateless Clustering |
|---|---|---|
| Load Balancer routing | Same user always routed to the same Node | Any Node can handle any request |
| Failover behavior | Session lost if the assigned Node fails, unless separately paired with replication | Seamless — any remaining Node retrieves the same session data |
| Reliance on cross-Node replication | Minimal to none by default | Essential and continuous |
| Operational complexity | Simpler Load Balancer configuration | Requires a properly tuned, healthy Infinispan cluster across all Nodes |
| Network overhead | Lower, since session data mostly stays local to one Node | Higher, due to continuous cross-Node replication traffic |
| Suitability for rolling deployments | Poor on its own — see Chapter 4 | Well suited — Nodes can be cycled without disrupting active sessions |
8Internal Working: A Request’s Journey Under Each Approach
Request Reaches the Load Balancer
Under both approaches, a user’s request first arrives at the Load Balancer, which must decide which Node will actually handle it.
Routing Decision Diverges
Under Sticky Sessions, the Load Balancer checks its own routing marker and sends the request back to the same Node as before. Under Stateless Clustering, it picks any available, healthy Node using its ordinary load-distribution logic.
Node Looks Up the Session
Under Sticky Sessions, the session is very likely already local to this Node. Under Stateless Clustering, the Node retrieves the session from the shared Infinispan cache, regardless of where it originated.
Request Is Processed
Once the session is found, either way, the Node processes the request exactly as it would in a single-server deployment.
Any Session Changes Are Propagated
If the request changes the session in any way, that update needs to reach the shared Infinispan cache so other Nodes can eventually see it too — a step that matters even under Sticky Sessions, to keep any eventual failover from using stale data.
9Embedded vs. External Infinispan
Embedded Infinispan
By default, each Keycloak Node runs its own embedded Infinispan instance, and these instances directly discover and communicate with one another to form a cluster. This is the simpler, out-of-the-box configuration, requiring no separate infrastructure beyond the Keycloak Nodes themselves.
External Infinispan (or an Alternative Distributed Cache)
For larger or more demanding deployments, Keycloak can instead be configured to rely on an externally run, separately managed distributed caching cluster, decoupling the caching layer’s own scaling and resilience characteristics from the Keycloak Nodes themselves.
Production Example: Choosing External Caching at Larger Scale
A large organization running many dozens of Keycloak Nodes across multiple data centers might move to an external caching setup specifically to gain more mature, independently scalable cache management, rather than relying on each Keycloak Node’s own embedded instance to handle that same scale of cross-Node coordination.
Decoupling Cache Lifecycle From Keycloak Node Lifecycle
A further, often underappreciated benefit of an external caching layer is that the cache’s own lifecycle becomes independent of any individual Keycloak Node’s lifecycle. Restarting or replacing a Keycloak Node no longer risks disturbing the cache cluster’s own internal stability, since the cache lives and is managed entirely separately — a meaningful operational simplification once a deployment reaches a scale where Keycloak Nodes themselves are being cycled frequently.
The Trade-off: Additional Infrastructure to Operate
This benefit doesn’t come free — an external caching cluster is itself a piece of infrastructure requiring its own monitoring, capacity planning, and operational ownership, distinct from the Keycloak Nodes it serves. For a smaller deployment, this added operational surface can outweigh the benefits described above, which is exactly why Keycloak’s simpler, embedded default remains the sensible starting point until an organization’s actual scale genuinely calls for something more.
10Why Most Modern Deployments Lean Toward Stateless Clustering
Containerized and Cloud-Native Environments Assume Nodes Come and Go
Modern deployment environments, particularly container orchestration platforms, are built around the assumption that individual server instances are disposable and can be replaced, rescheduled, or scaled up and down frequently and automatically. Sticky Sessions’ reliance on a stable, consistent mapping between a user and one specific Node sits awkwardly against this assumption, since a Node might be replaced by the orchestration platform at any moment for reasons entirely unrelated to any deliberate maintenance action.
True High Availability Requires Surviving a Node’s Failure Gracefully
As covered in Chapter 4, Sticky Sessions alone doesn’t provide real resilience against a Node actually failing — and a genuine production deployment’s high-availability goals generally require exactly this kind of resilience. Stateless Clustering directly delivers it, as its core, defining property.
None of this means Sticky Sessions is simply wrong or obsolete — for a smaller deployment with modest availability requirements, or one where the operational simplicity of avoiding continuous cross-Node replication genuinely outweighs the failover risk, Sticky Sessions remains a legitimate, simpler starting point.
11Data Flow & Lifecycle
Session Creation. A user logs in, and Keycloak creates a session on whichever Node happened to handle that specific login request.
Initial Replication. Regardless of the clustering approach chosen, the new session is generally written into the shared Infinispan cache, though how quickly and how reliably other Nodes are actually kept in sync can vary by configuration.
Ongoing Requests. Under Sticky Sessions, subsequent requests are routed back to the originating Node, which can serve them from its own local, already-current view of the session. Under Stateless Clustering, subsequent requests may land on any Node, each retrieving the session fresh from the shared cache.
Node Failure (if it occurs). Under Stateless Clustering, this is a routine, gracefully handled event. Under pure Sticky Sessions without adequate replication, this is where active sessions are actually lost, as covered in Chapter 4.
Session Expiry or Logout. Eventually, the session ends, either through explicit logout or reaching its configured expiration, and is cleaned up from the shared cache across the cluster.
graph LR
A["Session Created
on Originating Node"] --> B["Replicated to
Shared Infinispan Cache"]
B --> C{"Node Serving Next Request"}
C -->|"Sticky Sessions"| D["Same Node,
Local Data"]
C -->|"Stateless Clustering"| E["Any Node,
Fetched From Cache"]
D --> F["Session Ends
(Expiry or Logout)"]
E --> F
12Advantages, Disadvantages & Trade-offs
Sticky Sessions
- Simpler Load Balancer configuration, requiring no special routing awareness of session state
- Lower ongoing network overhead, since session data typically stays local to one Node
- A reasonable starting point for smaller, lower-availability-requirement deployments
- Poor resilience against a single Node’s failure, unless deliberately paired with additional replication
Stateless Clustering
- Genuine, seamless resilience against any single Node’s failure
- Naturally fits containerized, cloud-native environments where Nodes are frequently replaced
- Well suited to rolling deployments and dynamic scaling, without disrupting active sessions
- Higher network overhead and operational complexity, requiring a properly tuned, healthy Infinispan cluster at all times
13Security
Problem
A team deploys Keycloak with Sticky Sessions configured at the Load Balancer, and assumes this alone constitutes a genuinely highly-available deployment, without separately verifying whether session replication across Nodes is actually happening.
Why It Fails
As covered in Chapter 4, a Node failure under this configuration causes every session stuck to that Node to be lost outright — a real availability and continuity gap that can surface at the worst possible moment, during an actual incident, rather than during calm, planned testing.
Correct Approach
Explicitly decide, and verify through actual testing (deliberately taking a Node down in a non-production environment), whether the deployment’s session data genuinely survives a Node’s failure — treating this as a verified property of the deployment, not an assumption based on the Load Balancer’s configuration alone.
Cross-Node Replication Traffic Deserves Its Own Protection
Because session data — including details tied to an authenticated user’s identity — travels between Nodes as part of Infinispan’s replication under Stateless Clustering, this internal, Node-to-Node traffic deserves the same network-level protection (isolation, encryption where appropriate) as any other channel carrying sensitive authentication data, rather than being assumed safe simply because it stays within an internal network.
Load Balancer Session Cookies Need Their Own Security Review
Under Sticky Sessions, the cookie a Load Balancer uses to remember routing decisions is itself a piece of state worth reviewing for proper security attributes (such as being marked secure and appropriately scoped), exactly like any other cookie covered elsewhere in this series’ discussion of browser security headers.
A Compromised Node Under Each Approach
It’s worth considering what a single compromised Node can actually see under each approach. Under Sticky Sessions, a compromised Node primarily has direct, local access to the sessions of the specific users currently routed to it — a narrower, if still serious, exposure. Under Stateless Clustering, because every Node participates fully in the shared replicated cache, a compromised Node potentially has access to session data for any user across the entire cluster, not merely those it happened to serve directly. This doesn’t argue against Stateless Clustering’s real availability benefits, but it does mean the security hardening of each individual Node deserves consistent, uniform attention across the whole cluster, since a weakness in any single Node’s defenses has cluster-wide reach rather than being contained to that Node’s own directly served traffic.
14Monitoring, Logging & Metrics
Infinispan Cluster Health
Monitoring whether every Node’s embedded (or external) Infinispan instance is properly connected to the others is essential — a silently partitioned cache defeats the resilience Stateless Clustering is meant to provide.
Regular, Deliberate Node-Failure Drills
Periodically and deliberately taking a Node down in a controlled setting, and confirming active sessions genuinely survive, is the most reliable way to verify the resilience this architecture is meant to deliver, rather than discovering a gap during a real incident.
Per-Node Request Volume
Comparing request volume across Nodes reveals whether load is actually being distributed evenly, particularly relevant under Sticky Sessions, where an uneven distribution of “stuck” users can leave some Nodes far busier than others.
Cross-Node Replication Latency
Under Stateless Clustering, monitoring how quickly a session update actually propagates across Nodes helps catch a replication delay before it causes an inconsistent, confusing experience for a user whose requests land on different Nodes in quick succession.
Detecting a Silent Network Partition
One of the more insidious failure modes in a clustered deployment is a network partition — a situation where a subset of Nodes can no longer communicate with the rest of the cluster, yet each remains individually up and appears healthy on its own. Without dedicated cluster-membership monitoring specifically watching for this condition, a partition like this can persist for an extended period entirely unnoticed, quietly degrading the very resilience the cluster was built to provide, since replication across the partition boundary has effectively stopped even though no individual Node has actually crashed.
Alerting on Sustained, Not Momentary, Anomalies
As with the signature-verification monitoring covered elsewhere in this series, a brief, momentary blip in replication latency or per-Node load is often normal background noise in any sufficiently active distributed system. Effective alerting distinguishes this ordinary variability from a sustained, worsening trend that genuinely warrants investigation, keeping the operations team’s attention focused on real, emerging problems rather than routine fluctuation.
15Design Patterns & Anti-patterns
Good Patterns
- Choose deliberately, based on actual availability requirements, rather than defaulting to whichever approach happened to be easiest to configure initially
- Test failover explicitly and regularly, rather than assuming a chosen configuration provides the resilience it’s intended to
- Monitor Infinispan cluster health continuously, since a silently degraded cache undermines the whole architecture without necessarily producing an obvious, immediate symptom
- Favor Stateless Clustering for containerized or cloud-native deployments, where Nodes are expected to come and go dynamically
Anti-patterns to Avoid
Common Mistakes
- Assuming Sticky Sessions alone provides real high availability, as covered in Chapter 13
- Running Sticky Sessions in a container orchestration environment that reschedules Nodes frequently, guaranteeing frequent, unplanned session loss
- Never actually testing failover behavior in a non-production environment before relying on it in production
- Treating cross-Node replication traffic as inherently safe simply because it stays within an internal network
16Real-World & Industry Examples
Kubernetes-Hosted Keycloak Deployments
An organization running Keycloak inside a Kubernetes cluster, where individual pods are routinely rescheduled by the orchestration platform for entirely ordinary operational reasons, relies on Stateless Clustering almost by necessity — Sticky Sessions’ assumption of a stable Node-to-user mapping doesn’t hold up well against this kind of dynamic, self-managing infrastructure.
Financial Services With Strict Uptime Requirements
A bank or payment provider with contractual or regulatory uptime commitments typically requires genuine resilience against any single Node’s failure, making Stateless Clustering’s seamless failover a practical necessity rather than a nice-to-have architectural preference.
Smaller Internal Tools With Modest Availability Needs
An organization running Keycloak to authenticate a small set of internal tools, with a brief outage during a rare Node failure being a genuinely tolerable inconvenience rather than a serious incident, might reasonably choose Sticky Sessions for its operational simplicity, accepting the trade-off deliberately rather than by accident.
Multi-Region Deployments
An organization running Keycloak Nodes across geographically distant regions faces additional replication-latency considerations beyond a single-region cluster, often leading to a more carefully tuned external Infinispan (or equivalent) setup, as covered in Chapter 9, rather than relying on the simpler embedded default.
17Frequently Asked Questions
18Summary and Key Takeaways
Neither approach is a permanent architectural commitment carved in stone the moment it’s chosen — both are configuration decisions that can, and sometimes should, be revisited as a deployment’s scale, infrastructure, and availability expectations genuinely evolve over time. What matters most is that the choice is made deliberately, with its real trade-offs clearly understood, and verified through actual testing rather than assumed from the configuration screen alone.
Key Takeaways
- Sticky Sessions routes a user consistently back to the same Node, keeping session data local but leaving that session vulnerable if that specific Node fails.
- Stateless Clustering lets any Node handle any request, relying on Infinispan’s shared, replicated cache so every Node can access the same session data — providing genuine resilience against a Node’s failure.
- Both approaches rely on the same underlying Infinispan caching technology; the real distinction is whether cross-Node replication is actually depended on for failover, or treated as a secondary concern.
- Stateless Clustering is the generally preferred, modern default, particularly for containerized, cloud-native, or high-availability-requirement deployments.
- Sticky Sessions remains a legitimate, simpler choice for smaller deployments with modest availability requirements, chosen deliberately rather than by default.
- Always test failover explicitly — deliberately taking a Node down in a controlled setting — rather than assuming a chosen configuration delivers the resilience it’s meant to.
- Under Stateless Clustering, a compromised Node has cluster-wide reach into shared session data, so every Node’s security hardening deserves consistent, uniform attention.
- A silent network partition — where a subset of Nodes loses contact with the rest while each still appears individually healthy — can quietly disable replication without triggering an obvious symptom, so cluster-membership monitoring matters as much as individual Node health checks.
Ultimately, the right choice here isn’t a question of which approach is objectively superior in the abstract, but which one actually matches a specific deployment’s real availability requirements, its deployment environment’s own assumptions about Node stability, and the operational maturity a team can realistically sustain around a continuously replicated cache. A deployment that outgrows its original choice as its scale or requirements shift isn’t a sign anything was done wrong initially — it’s simply a natural point to revisit this same trade-off with fresh, current information, exactly as any other piece of foundational infrastructure occasionally deserves.