Sticky Session with Reverse Proxy in Clustered – Balanced Environments

In high-availability environments with multiple application nodes, the reverse proxy acts as a load balancer across backend servers. In these cases, managing a sticky session (or session affinity) is essential to keep the user bound to the same node throughout their session.
Why Use Sticky Sessions?
- Prevents session loss in environments without centralized session stores
- Ensures data consistency (e.g., login, cart, guided flows)
- Simplifies development when no shared store is used (e.g., Redis, DB)
- In rare cases, prevents session duplication, such as when two closely timed requests hit different nodes before the cookie has reached the browser and been sent back
Server-Side Approach
Each backend should identify itself with a unique route ID (e.g., xs22001
) and include it in the session cookie:
Set-Cookie: XSTORESESSION=abcdef123456.xs22001; Path=/; HttpOnly; SameSite=Lax
In Delphi, the logic might look like this:
function GetRouteSuffix: string;
begin
Result := 'xs' + IntToStr(Settings.porta_http);
end;
procedure SetSessionCookie(Response: TWebResponse; SessionID, RouteSuffix: string);
begin
Response.SetCookieField(
'',
'XSTORESESSION',
SessionID + '.' + RouteSuffix,
'/',
Now + 1,
True, // Secure
True, // HttpOnly
'Lax' // SameSite
);
end;
SameSite: Lax vs Strict
The SameSite
attribute is crucial when setting the session cookie:
- SameSite=Lax: allows the cookie to be sent even on cross-site navigation, such as clicks from Google, emails, or ads. This is the recommended setting to ensure the cookie is sent even on first visit.
- SameSite=Strict: the cookie is only sent during same-site navigation. This improves security but breaks sticky session behavior on first visits from external sources.
Apache Configuration
<Proxy "balancer://xstorecluster">
BalancerMember http://10.30.0.23:22001 route=xs22001
BalancerMember http://10.30.0.23:22002 route=xs22002
ProxySet stickysession=XSTORESESSION
</Proxy>
ProxyPass "/" "balancer://xstorecluster/"
ProxyPassReverse "/" "balancer://xstorecluster/"
Nginx Configuration
upstream xstorecluster {
ip_hash;
server 10.30.0.23:22001;
server 10.30.0.23:22002;
}
server {
listen 443 ssl;
server_name tecnomodelcar.com;
location / {
proxy_pass http://xstorecluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Final Considerations
When implementing sticky sessions, ensure that:
- The cookie includes a suffix that matches the route declared in the proxy
- The reverse proxy is configured to recognize and route based on that cookie
- Nodes do not implicitly share sessions (e.g., via unsynchronized local memory)
- The SameSite attribute is properly set to avoid session loss on first visit
Alternative: Centralized Sessions with Redis
Redis is a blazing-fast open source in-memory store, ideal for temporary data like user sessions.
Instead of sticky sessions, you can centralize session storage in a Redis instance shared by all backend servers:
- All nodes access the same store to read/write session data
- The user can hit any node without losing session state
- A persistent session ID is needed in the cookie
Advantages of Redis over sticky session:
- High scalability and fault tolerance
- No dependency on proxy routing
- Support for persistent, expiring, and multi-service sessions
Redis requires additional infrastructure and security measures, but it is the best choice in enterprise or microservice architectures.
Author: Ivan Revelli – Synaptica