Load Balancing with HAProxy
Load Balancing with HAProxy
Section titled “Load Balancing with HAProxy”A reverse proxy routes traffic to one upstream; a load balancer spreads traffic across many identical upstreams so you can scale out and survive the loss of any single instance. HAProxy is the reference open-source load balancer — extremely fast, with deep health-checking and observability.
If you only have a single app instance, you want a reverse proxy (nginx or Traefik), not this. Reach for a load balancer when one instance can’t carry the load or when downtime of a single instance is unacceptable.
L4 vs L7 balancing
Section titled “L4 vs L7 balancing”HAProxy can balance at two layers, and the choice drives everything else:
| Layer 4 (TCP) | Layer 7 (HTTP) | |
|---|---|---|
| Sees | IP + port only | Full HTTP — host, path, headers, cookies |
| Can route by URL/host | No | Yes |
| Can inject/read cookies | No | Yes (needed for app-cookie stickiness) |
| TLS | Pass-through or terminate | Terminate to inspect |
| Overhead | Lower | Slightly higher |
Use L4 for raw TCP services (databases, SMTP, or TLS pass-through). Use L7 when you need host/path routing, header manipulation, or cookie-based sticky sessions.
A working L7 config
Section titled “A working L7 config”global maxconn 20000 log /dev/log local0
defaults mode http timeout connect 5s timeout client 50s timeout server 50s option httplog
frontend web bind :443 ssl crt /etc/haproxy/certs/app.pem default_backend app_servers
backend app_servers balance roundrobin option httpchk GET /health # active health check http-check expect status 200 server app1 10.0.0.11:8080 check server app2 10.0.0.12:8080 check server app3 10.0.0.13:8080 check backup # only used if others are downHealth checks
Section titled “Health checks”The whole point of a load balancer is to stop sending traffic to a broken instance.
HAProxy marks a server DOWN after failed checks and UP again once it recovers:
option httpchk GET /health+http-check expect status 200— application-level check; far better than a bare TCP connect, because an app can accept connections while being unable to serve.- Tune with
server ... check inter 2s fall 3 rise 2(check every 2s; down after 3 failures, back up after 2 successes).
Sticky sessions
Section titled “Sticky sessions”If your app keeps per-user state in memory, a user must keep hitting the same backend. Two approaches:
# Cookie-based (L7) — HAProxy inserts a cookie naming the chosen serverbackend app_servers balance roundrobin cookie SRV insert indirect nocache server app1 10.0.0.11:8080 check cookie a1 server app2 10.0.0.12:8080 check cookie a2# Source-IP based (works at L4) — same client IP -> same serverbackend app_servers balance sourceHigh availability with Keepalived
Section titled “High availability with Keepalived”A single HAProxy is itself a single point of failure. Run two and float a virtual IP (VIP) between them with Keepalived (VRRP). DNS points at the VIP; if the primary dies, the backup claims the VIP within seconds.
# /etc/keepalived/keepalived.conf (primary)vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 200 # backup uses a lower priority (e.g. 100) virtual_ipaddress { 10.0.0.10/24 # the VIP clients connect to } track_script { chk_haproxy } # demote if local HAProxy is down}HAProxy vs nginx vs Traefik
Section titled “HAProxy vs nginx vs Traefik”| HAProxy | nginx | Traefik | |
|---|---|---|---|
| Primary role | Load balancer | Reverse proxy / web server | Container-native proxy |
| L4 (TCP) balancing | Excellent | Good (stream) | Limited |
| Health checking | Deepest | Basic (open-source) | Good |
| Auto certs | No | No (Certbot) | Yes |
| Config style | Static file | Static file | Docker labels |
For most self-hosted setups, nginx or Traefik is enough. Add HAProxy when you specifically need its load-balancing and health-checking depth, or L4 balancing.
Related
Section titled “Related”- Reverse Proxy with nginx — single-upstream proxying and TLS
- Reverse Proxy with Traefik — dynamic container routing
- Docker — running balanced services as containers
- Linux Networking with Netplan — the network layer beneath the VIP