StackPractices
intermediate By Mathias Paulenko

Load Balancing with HAProxy and Health Checks

Configure HAProxy as a high-performance load balancer with active health checks, sticky sessions, and SSL termination for resilient service distribution

Distribute incoming traffic across multiple backend servers using HAProxy, a high-performance TCP/HTTP load balancer. The solution below covers round-robin distribution, active health checks, sticky sessions, and SSL termination for production-grade resilience.

When to Use This

  • You run multiple application instances and need to distribute traffic evenly. See Health Check Endpoint for backend health probes.
  • Services must be automatically removed from rotation when unhealthy. See Circuit Breaker for failure isolation.
  • SSL termination should happen at the edge, not on each application server. See Nginx Reverse Proxy for edge proxy patterns.

Solution

1. Basic HAProxy Configuration

# haproxy.cfg
global
    log stdout local0
    maxconn 4096

defaults
    mode http
    timeout connect 5s
    timeout client 30s
    timeout server 30s
    option httpchk GET /health

frontend web_frontend
    bind *:80
    default_backend app_servers

backend app_servers
    balance roundrobin
    server web1 10.0.1.10:3000 check
    server web2 10.0.1.11:3000 check
    server web3 10.0.1.12:3000 check

2. Active Health Checks

backend app_servers
    balance roundrobin
    option httpchk GET /health

    # Mark as down after 2 failed checks; up after 3 successes
    default-server inter 5s fall 2 rise 3

    server web1 10.0.1.10:3000 check
    server web2 10.0.1.11:3000 check
    server web3 10.0.1.12:3000 check

3. Sticky Sessions with Cookies

backend app_servers
    balance roundrobin
    cookie SERVERID insert indirect nocache

    server web1 10.0.1.10:3000 check cookie web1
    server web2 10.0.1.11:3000 check cookie web2
    server web3 10.0.1.12:3000 check cookie web3

4. SSL Termination

frontend web_frontend
    bind *:443 ssl crt /etc/ssl/certs/site.pem
    http-request redirect scheme https unless { ssl_fc }
    default_backend app_servers

5. Stats Dashboard

listen stats
    bind *:8404
    stats enable
    stats uri /stats
    stats refresh 10s

How It Works

  • Frontend listens on a port and receives client connections
  • Backend defines the pool of servers and balancing algorithm
  • Health checks send periodic requests; failing servers are removed
  • Cookie insertion pins a user to a specific backend for session affinity

Variation: Weighted Load Balancing

backend app_servers
    balance roundrobin
    server web1 10.0.1.10:3000 check weight 3
    server web2 10.0.1.11:3000 check weight 2
    server web3 10.0.1.12:3000 check weight 1

Production Considerations

  • Run HAProxy in active-passive with keepalived for failover
  • Use leastconn for long-lived WebSocket connections
  • Enable compression with compression algo gzip

Common Mistakes

  • Forgetting to expose a /health endpoint in applications
  • Using source IP affinity behind NAT where all clients share one IP
  • Not monitoring the stats page for backend degradation

Performance Tips

  1. Tune maxconn based on available memory. Each connection uses ~200 bytes. For 10K connections, allocate ~2MB:
global
    maxconn 10000
    nbproc 4  # Use multiple processes for multi-core CPUs
  1. Use nbthread for multi-threaded mode. HAProxy 2.0+ supports threads:
global
    nbthread 4
    cpu-map auto:1/1-4 0-3
  1. Enable splice-request and splice-response for TCP. Uses kernel splice for zero-copy forwarding:
defaults
    mode tcp
    option splice-request
    option splice-response
  1. Use tune.ssl.default-dh-param for SSL performance. Set to 2048 or higher:
global
    tune.ssl.default-dh-param 2048
  1. Monitor with HAProxy stats socket. Export metrics to Prometheus for alerting:
# Enable stats socket
echo "stats socket /var/run/haproxy.sock mode 660 level admin" >> haproxy.cfg

# Query stats
echo "show info" | socat /var/run/haproxy.sock -
echo "show servers state" | socat /var/run/haproxy.sock -

Frequently Asked Questions

How is this different from Nginx?

HAProxy specializes in layer 4/7 load balancing with superior health check granularity. Nginx is a general-purpose web server that also proxies.

Can I use HAProxy with Docker?

Yes. Use the official haproxy image and mount your haproxy.cfg as a volume.