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
Note: This guide follows English-language naming conventions and terminology standards common in international development teams. Examples use English identifiers and comments to maximize compatibility across codebases and tooling.
Load Balancing with HAProxy and Health Checks
Distribute incoming traffic across multiple backend servers using HAProxy, a high-performance TCP/HTTP load balancer. This recipe 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
- Services must be automatically removed from rotation when unhealthy
- SSL termination should happen at the edge, not on each application server
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
leastconnfor long-lived WebSocket connections - Enable compression with
compression algo gzip
Common Mistakes
- Forgetting to expose a
/healthendpoint in applications - Using source IP affinity behind NAT where all clients share one IP
- Not monitoring the stats page for backend degradation
FAQ
Q: How is this different from Nginx? A: HAProxy specializes in layer 4/7 load balancing with superior health check granularity. Nginx is a general-purpose web server that also proxies.
Q: Can I use HAProxy with Docker?
A: Yes. Use the official haproxy image and mount your haproxy.cfg as a volume.