Complete GuideHAProxy25 min read

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.

PS
PentaSynth Team
August 10, 2024 · Updated March 2025

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.cfg

2. 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.

AlgorithmBest ForConfig
roundrobinStateless APIs, equal server capacitybalance roundrobin
leastconnWebSockets, DB proxying, long connectionsbalance leastconn
sourceSimple session affinity by client IPbalance source
uriCache-friendliness, CDN backendsbalance uri
url_paramRoute by URL parameter (e.g., user_id)balance url_param user_id
hdrRoute by HTTP header valuebalance hdr(Host)
randomSimple horizontal scalingbalance random
static-rrroundrobin without dynamic weight changesbalance 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 2

MySQL 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 backup

Redis 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 backup

4. 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 app3

Source 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 check

5. 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_servers

For 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-keepalive

8. 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.sock

10. 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.

See Our Services

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