HAProxy
HAProxy is an open-source load balancer and reverse proxy known for raw performance, reliability, and precise control over traffic. It balances TCP (layer 4) and HTTP (layer 7) traffic across backend servers, terminates TLS, routes by host, path, or header, health-checks servers, enforces rate limits, and exposes detailed metrics — handling hundreds of thousands of connections on modest hardware. Many large websites, cloud load balancers, and Kubernetes ingress controllers are built on it.
Where Nginx is a web server that also proxies, HAProxy is a proxy first: its configuration language, health checking, connection management, and runtime control are designed entirely around moving traffic to backends safely.
TL;DR
- Configuration is organized into
global,defaults,frontend(where traffic arrives), andbackend(where it goes) sections. - ACLs match requests by path, host, headers, source, and more, and
use_backendroutes on them. - Choose a balance algorithm:
roundrobin,leastconn,source,uri,hdr, orrandom. - Active health checks remove failing servers automatically;
maxconnper server protects backends from overload. - Stick tables track clients for rate limiting, abuse detection, and session persistence.
- The runtime API drains and re-enables servers without reloads; master-worker mode gives hitless reloads.
Quick Example
An HTTPS frontend with routing, rate limiting, and two health-checked backends:
Core Concepts
Sections
Modes: TCP and HTTP
In mode tcp, HAProxy forwards bytes without parsing them — suitable for databases, message brokers, or TLS passthrough, using SNI for routing. In mode http, it parses each request, enabling routing on paths and headers, header rewriting, HTTP health checks, compression, and HTTP/2 and HTTP/3 support.
Balancing Algorithms
Health Checks and Protection
Active checks probe each server on an interval; rise and fall control how many results change its state. Per-server maxconn queues excess requests in HAProxy instead of overwhelming a backend, and timeout queue bounds that wait. Passive observation (observe layer7) can also mark servers down on error responses.
Stick Tables
Stick tables are in-memory key-value tables keyed by IP, header, or cookie, storing counters such as request rate, connection count, and error rate. They power rate limiting, brute-force protection, and persistence, and can be synchronized between HAProxy peers. See Nginx Rate Limiting for the comparable Nginx approach.
Operating HAProxy
Runtime API
The stats socket exposes commands to inspect and change state without reloading: show servers and stats, set server weights, put servers into drain (finish existing connections, accept none) or maint mode, and update maps and ACLs. Deployment tooling uses it to remove servers from rotation before upgrades.
Reloads Without Dropped Connections
In master-worker mode (-W, the default with systemd packages), a reload starts new workers with the new configuration while old workers finish their connections. With expose-fd listeners, the listening sockets are passed to the new process so no connection attempts are refused during the switch.
Observability
HAProxy logs detailed timing for every request — time to connect, server response time, total time, termination state — which makes slow backends easy to pinpoint. A built-in Prometheus exporter and the stats page expose per-frontend, per-backend, and per-server metrics.
High Availability
A single HAProxy instance is a single point of failure. Common designs run two or more instances with a floating IP managed by keepalived (VRRP), or several active instances behind DNS or a cloud network load balancer. See High Availability.
Best Practices
Set Timeouts Explicitly
Define timeout connect, client, server, http-request, and queue. Missing or huge timeouts let slow clients and stuck backends exhaust connections. Long-lived WebSocket traffic needs timeout tunnel.
Protect Backends With maxconn
Size per-server maxconn to what each backend can actually handle, and let HAProxy queue the rest. Queuing in the proxy is far cheaper than overloading application servers.
Validate and Version Configuration
Keep haproxy.cfg in version control, run haproxy -c in CI and before every reload, and template environment-specific values.
Use Real Health Endpoints
Check an endpoint that verifies the application can serve requests, not just that the port is open — but keep it cheap, and avoid failing all servers at once when a shared dependency is down.
Common Mistakes
TCP Checks for HTTP Services
Losing the Client IP
Restarting Instead of Reloading
FAQ
What is HAProxy used for?
Load balancing and reverse proxying TCP and HTTP traffic: distributing requests across servers, terminating TLS, routing by host or path, health checking, rate limiting, and providing detailed traffic metrics.
Is HAProxy better than Nginx?
For pure load balancing, HAProxy offers richer health checks, stick tables, runtime control, and detailed per-request timing. Nginx is a web server as well, serving static files and acting as an application gateway. Many architectures use both.
Does HAProxy support HTTP/2 and HTTP/3?
Yes. HAProxy supports HTTP/2 on frontends and backends, and HTTP/3 over QUIC in recent versions when built with a QUIC-capable TLS library.
How do I remove a server without dropping traffic?
Use the runtime API to set the server to drain, wait for its connections to finish, then perform maintenance and set it back to ready. Health checks can also take it out automatically when it stops responding.
How does HAProxy rate limiting work?
Stick tables track counters such as request rate per client key. HTTP rules then deny, tarpit, or slow down clients whose counters exceed thresholds, optionally sharing tables across HAProxy peers.
Related Topics
- Load Balancing — Algorithms and architectures
- Nginx — Web server and reverse proxy
- High Availability — Removing single points of failure
- HTTPS and TLS — Certificates and termination
- Nginx Rate Limiting — Rate limiting at the proxy
- Kubernetes Networking — Ingress controllers built on proxies