HAProxy Load Balancing: Complete Production Setup Guide with Config Examples (2025)
Everything you need to run HAProxy in production: load balancing algorithms, advanced health checks, sticky sessions, SSL termination, active-passive high availability with Keepalived, and performance tuning for high-traffic workloads.
1. Installation
HAProxy is available in most Linux package managers. Always install the latest stable version:
# Ubuntu/Debian
apt-get install --no-install-recommends software-properties-common
add-apt-repository ppa:vbernat/haproxy-2.9
apt-get install haproxy=2.9.*
# RHEL/CentOS/Amazon Linux
yum install haproxy
# Verify installation
haproxy -v
# HAProxy version 2.9.x
# Check config syntax before applying
haproxy -c -f /etc/haproxy/haproxy.cfg2. Load Balancing Algorithms Compared
HAProxy supports 8 load balancing algorithms. Choosing the right one for your workload is one of the most impactful performance decisions you'll make.
| Algorithm | Best For | Config |
|---|---|---|
| roundrobin | Stateless APIs, equal server capacity | balance roundrobin |
| leastconn | WebSockets, DB proxying, long connections | balance leastconn |
| source | Simple session affinity by client IP | balance source |
| uri | Cache-friendliness, CDN backends | balance uri |
| url_param | Route by URL parameter (e.g., user_id) | balance url_param user_id |
| hdr | Route by HTTP header value | balance hdr(Host) |
| random | Simple horizontal scaling | balance random |
| static-rr | roundrobin without dynamic weight changes | balance static-rr |
Weighted Load Balancing
Give more powerful servers a higher weight to receive proportionally more traffic:
backend web_servers
balance roundrobin
server app1 10.0.0.1:8080 weight 3 check # Gets 3x more traffic
server app2 10.0.0.2:8080 weight 2 check # Gets 2x more traffic
server app3 10.0.0.3:8080 weight 1 check # Gets 1x traffic (smallest server)3. Advanced Health Checks
Basic health checks only verify a server is listening. Advanced health checks verify your application is actually functioning correctly.
Application-Aware HTTP Health Checks
backend api_servers
option httpchk GET /health HTTP/1.1
http-check send hdr Host api.example.com
http-check expect status 200
# Agent check — let the app control its own weight
option external-check
external-check path "/usr/lib/nagios/plugins"
external-check command check_http
server api1 10.0.0.1:3000 check inter 2s fall 3 rise 2
server api2 10.0.0.2:3000 check inter 2s fall 3 rise 2MySQL Health Check
backend mysql_servers
option mysql-check user haproxy_check
server db1 10.0.0.10:3306 check
server db2 10.0.0.11:3306 check backupRedis Health Check
backend redis_servers
option tcp-check
tcp-check connect
tcp-check send PING
tcp-check expect string +PONG
tcp-check send QUIT
tcp-check expect string +OK
server redis1 10.0.0.20:6379 check inter 1s
server redis2 10.0.0.21:6379 check inter 1s backup4. Sticky Sessions (Session Persistence)
When your application stores session state on individual servers, you need sticky sessions to ensure the same client always reaches the same server.
Cookie-Based Stickiness (Recommended)
backend web_servers
balance roundrobin
# HAProxy inserts a cookie to track which server the client uses
cookie SERVERID insert indirect nocache
server app1 10.0.0.1:8080 check cookie app1
server app2 10.0.0.2:8080 check cookie app2
server app3 10.0.0.3:8080 check cookie app3Source IP Stickiness
backend web_servers
balance source
hash-type consistent # Use consistent hashing to minimize reshuffling when servers change
server app1 10.0.0.1:8080 check
server app2 10.0.0.2:8080 check5. SSL Termination
SSL termination at HAProxy removes the TLS overhead from your application servers and gives you centralized certificate management.
global
ssl-default-bind-options ssl-min-ver TLSv1.2 no-sslv3
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
frontend web_frontend
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1
# Store the original protocol header for apps that need it
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Port %[dst_port]
# Redirect HTTP to HTTPS
http-request redirect scheme https code 301 unless { ssl_fc }
default_backend web_serversFor Let's Encrypt integration, see our full guide: HAProxy SSL Termination with Let's Encrypt
6. High Availability with Keepalived
A single HAProxy instance is a single point of failure. Use Keepalived to create an active-passive HA pair that automatically fails over if the primary goes down.
Architecture
Two HAProxy servers share a Virtual IP (VIP). The primary server holds the VIP and handles all traffic. If the primary fails, Keepalived promotes the secondary and reassigns the VIP — typically within 1-2 seconds.
Keepalived Config (Primary)
# /etc/keepalived/keepalived.conf (Primary node)
vrrp_script chk_haproxy {
script "/usr/bin/killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 101 # Higher priority = primary
authentication {
auth_type PASS
auth_pass YourSecurePassword
}
virtual_ipaddress {
192.168.1.100/24 # Your Virtual IP
}
track_script {
chk_haproxy
}
}Keepalived Config (Secondary)
# /etc/keepalived/keepalived.conf (Secondary node)
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100 # Lower priority = secondary
authentication {
auth_type PASS
auth_pass YourSecurePassword
}
virtual_ipaddress {
192.168.1.100/24 # Same Virtual IP
}
}7. Performance Tuning
global
# Match nbthread to your CPU core count
nbthread 8
cpu-map auto:1/1-8 0-7
# Tune the socket buffers
tune.bufsize 32768
tune.maxrewrite 8192
# Connection limits
maxconn 200000
# Spread load across threads more evenly
nbthread 8
defaults
# Use HTTP/1.1 keep-alive for backend connections
option http-server-close
option forwardfor
# Tune timeout values for your workload
timeout connect 3s
timeout client 60s
timeout server 60s
backend web_servers
balance roundrobin
# Enable connection pooling to backends
option http-server-close
option http-pretend-keepalive8. Monitoring & Logging
global
log /dev/log local0 info
defaults
log global
# Log format includes response time, server used, bytes
option httplog
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %tsc %ac/%fc/%bc/%sc/%rc %{+Q}r"
frontend stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:secure_password
stats hide-version
frontend prometheus
bind *:8405
http-request use-service prometheus-exporter if { path /metrics }9. Zero-Downtime Blue-Green Deployments
HAProxy's runtime API lets you switch traffic between blue and green environments without any downtime or config file changes:
# haproxy.cfg with both blue and green backends
backend blue_servers
server blue1 10.0.1.1:8080 check
server blue2 10.0.1.2:8080 check
backend green_servers
server green1 10.0.2.1:8080 check disabled # Start disabled
server green2 10.0.2.2:8080 check disabled
# Switch traffic to green via runtime API (zero downtime):
echo "enable server green_servers/green1" | nc -U /var/run/haproxy/admin.sock
echo "enable server green_servers/green2" | nc -U /var/run/haproxy/admin.sock
echo "disable server blue_servers/blue1" | nc -U /var/run/haproxy/admin.sock
echo "disable server blue_servers/blue2" | nc -U /var/run/haproxy/admin.sock10. Common Issues & Troubleshooting
Problem: "Cannot bind socket" error on startup
Solution: HAProxy needs to bind to the IP/port before the network interface is fully up. Add "net.ipv4.ip_nonlocal_bind=1" to /etc/sysctl.conf, or ensure HAProxy starts after networking.
Problem: High latency on SSL connections
Solution: Enable session resumption with "tune.ssl.cachesize 100000" and "tune.ssl.lifetime 300" in the global section. Also ensure you're using TLS 1.3 which has faster handshakes.
Problem: Backends showing as DOWN immediately
Solution: Check the health check URL is returning 200. Add "option allbackups" to prevent HAProxy from removing all servers. Use "haproxy -d" in debug mode to see health check details.
Problem: 504 Gateway Timeout errors
Solution: Increase timeout server and timeout tunnel values. For WebSockets, set "timeout tunnel 3600s". Check if backend servers are actually responding within your timeout window.
Need a production HAProxy setup?
We design and implement production-grade load balancing with HAProxy, including HA failover, SSL termination, DDoS protection, and monitoring.
Let Us Handle HAProxy in Production
PentaSynth sets up HAProxy with full high-availability, Keepalived failover, SSL termination, rate limiting, and Prometheus monitoring — as part of our DevOps & Cloud service.
Get a Free Architecture Review