How to Route Traffic to Specific Servers Based on Cookies in HAProxy: A Practical Guide


9 views

HAProxy's ACL (Access Control List) system combined with cookie parsing makes it possible to route traffic to specific backend servers based on cookie values. This is particularly useful for:

  • Sticky sessions implementation
  • A/B testing deployments
  • Multi-tenant architectures
  • Canary releases

Here's a complete configuration example for routing traffic based on the "loginCreds" cookie:

frontend http-in
    bind *:80
    acl company_a req.cook(loginCreds) -m sub CompanyA
    acl company_b req.cook(loginCreds) -m sub CompanyB
    use_backend servers_a if company_a
    use_backend servers_b if company_b
    default_backend servers_default

backend servers_a
    server serverA 192.168.1.10:80 check

backend servers_b
    server serverB 192.168.1.11:80 check

backend servers_default
    server serverDefault 192.168.1.12:80 check

For more complex scenarios, you can use regex matching:

acl premium_user req.cook(loginCreds) -m reg :Premium$
use_backend premium_servers if premium_user

Or combine multiple conditions:

acl vip_user req.cook(loginCreds) -m sub CompanyA req.cook(userType) -m str VIP
use_backend vip_servers if vip_user

When implementing cookie-based routing:

  • Cookie parsing adds slight overhead - benchmark with your traffic patterns
  • Consider using req.cook_val() instead of req.cook() for exact matches
  • For high-traffic sites, pre-compile ACL patterns using -m reg with simple patterns

Common issues and solutions:

# Check cookie values in logs:
capture request header Cookie len 512

# Debug ACL matches:
http-request set-var(txn.debug) req.cook(loginCreds)
log-format %[var(txn.debug)]

Remember to test your configuration with haproxy -c -f /etc/haproxy/haproxy.cfg before applying changes.


HAProxy's cookie-based routing is a game-changer for session persistence and A/B testing scenarios. When you need to maintain user stickiness to specific backend servers based on session cookies, this approach provides an elegant solution.

Here's the essential HAProxy configuration to achieve cookie-based routing:

frontend http-in
    bind *:80
    acl is_companyA req.cook(loginCreds) -m sub :CompanyA
    acl is_companyB req.cook(loginCreds) -m sub :CompanyB
    use_backend servers_companyA if is_companyA
    use_backend servers_companyB if is_companyB
    default_backend servers_default

backend servers_companyA
    cookie SERVERID insert indirect nocache
    server serverA 192.168.1.10:80 check cookie serverA

backend servers_companyB
    cookie SERVERID insert indirect nocache
    server serverB 192.168.1.20:80 check cookie serverB

backend servers_default
    server default1 192.168.1.30:80 check

For more complex cookie matching logic, consider these approaches:

# Match exact cookie value
acl is_john req.cook(loginCreds) John:CompanyA

# Regex pattern matching
acl is_companyA_user req.cook(loginCreds) -m reg :CompanyA$

# Cookie presence check
acl has_login_cookie req.cook(loginCreds) -m found

When implementing cookie-based routing, remember:

  • Always configure proper fallback mechanisms
  • Consider adding health checks for your backend servers
  • Test cookie handling with different browser behaviors
  • Monitor the stickiness ratio to ensure proper balancing

Enable debugging in HAProxy with:

global
    log /dev/log local0 debug

frontend http-in
    capture request header Cookie len 64

This will help track cookie values being processed by HAProxy.