HAProxy can feel like a black box, but it’s actually designed to be incredibly transparent and controllable.

Let’s see HAProxy in action. Imagine you have two backend web servers, web1 on 192.168.1.10:80 and web2 on 192.168.1.11:80. You want HAProxy to distribute traffic between them. Here’s a minimal haproxy.cfg:

global
    log /dev/log    local0
    daemon

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

frontend http_in
    bind *:80
    default_backend http_back

backend http_back
    balance roundrobin
    server web1 192.168.1.10:80 check
    server web2 192.168.1.11:80 check

When a client connects to HAProxy on port 80, HAProxy inspects the incoming HTTP request. Based on the balance roundrobin setting in the backend http_back section, it picks the next server in line to forward that request to. check tells HAProxy to periodically ping web1 and web2 to ensure they’re healthy, and it will stop sending traffic to any server that fails its checks.

This setup solves the problem of needing a single, reliable entry point for your web application, even if your backend servers are numerous or prone to occasional failures. HAProxy acts as a traffic cop, directing incoming requests to available servers and ensuring high availability. The global section sets up logging and runs HAProxy as a background process. defaults provides common settings for both frontends and backends, like connection timeouts. The frontend http_in defines where HAProxy listens for incoming traffic (*:80 means all interfaces, port 80) and which backend to use (default_backend http_back). The backend http_back defines the pool of servers that will handle the requests and how traffic is distributed among them.

The balance directive is your primary tool for controlling distribution. roundrobin is simple and equitable, but for more sophisticated needs, you can use leastconn (sends traffic to the server with the fewest active connections), source (hashes the client IP to consistently send a client to the same server, good for sticky sessions without cookies), or even custom algorithms. The server lines specify the actual backend servers, their IP addresses and ports, and crucially, the check option. Without check, HAProxy would happily send traffic to a dead server, defeating the purpose of load balancing.

HAProxy’s ability to perform health checks is more than just a simple ping. It can be configured to expect specific responses. For instance, instead of just check, you could use httpchk GET /health. This tells HAProxy to make an HTTP GET request to /health on the backend server and expect a 2xx or 3xx status code. If it gets anything else, or a timeout, the server is marked down. This is far more robust than a basic TCP check.

Many people overlook the power of HAProxy’s statistics page. By adding a listen stats section to your haproxy.cfg, you get a live, interactive dashboard:

listen stats
    bind *:8080
    mode http
    stats enable
    stats uri /haproxy?stats
    stats auth admin:password

Accessing http://your-haproxy-ip:8080/haproxy?stats in your browser (after replacing admin:password with your chosen credentials) will show you real-time connection counts, response times, error rates, and server status for all your frontends and backends. It’s an invaluable tool for understanding traffic flow and diagnosing issues.

When you need to ensure a client consistently hits the same backend server, often for applications that store session state locally, you’ll use HAProxy’s cookie-based session persistence. Instead of balance source, you’d add cookie SERVERID to your backend servers and then use cookie SERVERID insert indirect in your frontend. This tells HAProxy to add a SERVERID cookie to responses going to the client. On subsequent requests from that client, HAProxy will look for this cookie and route the request to the server that originally set it, even if other load balancing algorithms are also defined.

The next concept you’ll encounter is fine-tuning HAProxy’s performance and security, often involving TLS termination and advanced request routing.

Want structured learning?

Take the full Computer Networking course →