Sticky Sessions
Sticky sessions, also known as session affinity or session persistence, is a load balancing technique that ensures subsequent requests from the same client are routed to the same backend server for the duration of a session. This maintains session state (e.g., user login, shopping cart) on one server, avoiding the need for shared storage. Introduced in early web load balancers (e.g., 1990s), sticky sessions remain essential for stateful apps in microservices, despite alternatives like centralized sessions.
Fundamental Concepts
1. What is a Session?
- Definition: A logical conversation between client and server, often tracked by a unique identifier (session ID).
- Stateful vs Stateless: Stateful sessions store data server-side (e.g., user prefs in memory); stateless use tokens (e.g., JWT in client cookies).
- Why State Matters: Without affinity, requests scatter across servers, losing context (e.g., cart items vanish).
2. Load Balancing Basics
- Problem: Multiple servers (pool) handle traffic for scalability; balancer distributes requests.
- Without Sticky Sessions: Round-robin or least-connections → session data lost on server switch.
- With Sticky Sessions: Balancer "sticks" client to one server using a key (e.g., cookie, IP).
3. Affinity Key
- Definition: The identifier used to map client to server.
-
Types: | Key Type | How | Pros | Cons | |----------|-----|------|------| | Cookie-Based | Server sets cookie (e.g.,
JSESSIONID) with server ID. | Accurate; works with NAT. | Client must accept cookies. | | IP-Based (Source IP Hash) | Hash client IP to server. | No client changes. | Poor for NAT/shared IPs (all route to one server). | | Header-Based | Custom header (e.g.,X-Session-ID). | Flexible. | App must set header. | -
Duration: Session cookie (expires on browser close) or persistent (fixed time, e.g., 30min).
4. Load Balancer Role
- Balancer Types: Hardware (F5), software (NGINX, HAProxy), cloud (AWS ALB, GCP LB).
- Mechanism: On request, balancer checks affinity key → routes to matching server; sets/updates key if new.
How Sticky Sessions Work (Step-by-Step)
- Initial Request: Client hits balancer (e.g., round-robin selects Server A).
- Server Assignment: Balancer notes affinity (e.g., sets cookie
server_id=A). - Session Start: Server A creates session data (e.g., stores cart in memory).
- Subsequent Requests: Client resends cookie/key; balancer routes back to Server A.
- Session End: Timeout, explicit logout, or cookie expiration → reassign.
Diagram:
Client ──(Request + No Cookie)──► Balancer ──► Server A (Assigns Cookie)
Client ──(Request + Cookie A)───► Balancer ──► Server A (Session Data)
Client ──(Request + Cookie A)───► Balancer ──► Server B? No → Server A
Implementation Examples
NGINX (Cookie-Based)
upstream backend {
server srv1.example.com;
server srv2.example.com;
sticky cookie srv_id expires=1h domain=.example.com path=/;
}
server {
location / {
proxy_pass http://backend;
}
}
- How: NGINX sets
srv_idcookie with server name; routes on match.
HAProxy (IP Hash)
backend webservers
balance source # IP hash
server srv1 192.168.1.10:80 check
server srv2 192.168.1.11:80 check
- How: Hashes client IP to consistent server.
Kubernetes Service (Session Affinity)
apiVersion: v1
kind: Service
spec:
sessionAffinity: ClientIP # IP-based
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800 # 3 hours
ports:
- port: 80
targetPort: 8080
- How: Kube-proxy sets affinity for traffic to Pods.
Pros and Cons
| Pros | Cons |
|---|---|
| Simplicity: No shared storage needed. | Uneven Load: Some servers overloaded if sticky. |
| Performance: Low latency (no session lookup). | Failover Issues: Session lost on server failure. |
| Compatibility: Works with legacy apps. | Scalability Limit: Can't freely add/remove servers mid-session. |
Alternatives to Sticky Sessions
- Centralized Sessions: Store in Redis/DB (e.g.,
session['cart'] = items); stateless servers. - JWT Tokens: Client-side state (signed, self-contained).
- Serverless: AWS Lambda uses stateless functions; sessions in DynamoDB.
- When to Switch: For horizontal scaling; sticky = quick fix for legacy.
Best Practices: - Use cookies over IP (handles NAT). - Set short timeouts (e.g., 30min) for security. - Monitor Affinity: Check load distribution; fallback to shared if uneven. - Graceful Failover: Use session replication or sticky with replication.