RousselTMLEARNING

Proxy & networking

Session persistence (stickiness)

Understanding how to ensure a user stays on the same backend server for the whole session.

1. Cookie-based persistence #

The most reliable method for HTTP applications.

Cookie insertion #

HAProxy inserts a cookie into the server's response. When the client comes back, it reads this cookie to know which server to send the request to.

backend app_servers
    balance roundrobin
    cookie SERVERID insert indirect nocache
    server s1 10.0.0.1:80 check cookie s1
    server s2 10.0.0.2:80 check cookie s2

2. Source IP persistence #

Used when the application does not handle cookies, or for non-HTTP traffic.

The source algorithm #

The user's IP is hashed to designate a server. Simple, but problematic if many users share the same IP (e.g. a company behind a proxy).

backend app_servers
    balance source
    server s1 10.0.0.1:80 check

3. Stick-tables #

HAProxy's internal memory for advanced persistence.

In-memory storage #

Stick-tables store information (IP, session ID) and can share it between several HAProxy nodes through peers.

backend myapp
    stick-table type ip size 100k expire 30m
    stick on src

Conclusion #

Maintaining user state.

Choosing the right method #

Cookies are preferred for the web, while source IP or stick-tables are essential for complex persistent flows (TCP, RDP, etc.).

Hands-on: configuring persistence #

Cookies, stick-tables and tests.

Cookie-based persistence #

backend app
    balance roundrobin
    cookie SRV insert indirect nocache httponly secure
    server web1 10.0.0.11:8080 check cookie s1
    server web2 10.0.0.12:8080 check cookie s2
curl -sI https://app.exemple.fr | grep -i set-cookie            # Set-Cookie: SRV=s1; ...
for i in 1 2 3 4; do curl -s -b "SRV=s2" https://app.exemple.fr/hostname; done   # toujours web2

IP-based persistence with a stick-table #

backend app
    balance roundrobin
    stick-table type ip size 200k expire 30m
    stick on src
    server web1 10.0.0.11:8080 check
    server web2 10.0.0.12:8080 check
echo "show table app" | sudo socat stdio /var/run/haproxy.sock     # entrées de la table
echo "clear table app key 203.0.113.7" | sudo socat stdio /var/run/haproxy.sock
Common mistake: Behind a CDN or proxy, src is the proxy's address: use stick on req.hdr_ip(X-Forwarded-For,-1) or an application cookie to avoid sending everything to the same server.

Related articles

Anatomy of HAProxy configuration, clustering and high availability

Understand the structure of an haproxy.cfg file: the global, defaults, frontend (high performance), backend a…

HAProxy in Kubernetes: the high-performance Ingress Controller

Discover in depth how HAProxy integrates with Kubernetes: direct-to-pod architecture, hot update options (DNS…

What's new in HAProxy: OpenTelemetry, native JWT and performance optimizations

Explore HAProxy's latest innovations: native OpenTelemetry support for observability, JWT validation at the e…

Keep learning

Support us

♥ SUPPORT US

Support RousselTM Learning

Courses, articles, labs and certificates stay free with no intrusive ads. A voluntary contribution, of any amount you choose, pays for hosting, lab environments and new content.

Contribute with PayPal Any amount · card or PayPal accountLearn more
QR code PayPal
Or scan this QR code with your phone

Thank you, every contribution counts!