An HAProxy configuration file is short compared with most server software, yet it decides how every request reaches your application. If you are about to put a load balancer in front of a website or API as a step toward a high availability server setup, or have inherited one that nobody fully understands, it helps to read the file section by section. This guide walks through a typical HAProxy configuration for a web application on the current 3.x releases: what each part does, which options matter most and the mistakes that cause outages.

The four sections of an HAProxy configuration

  • global sets process-wide options: logging, the user HAProxy runs as, TLS defaults and the admin socket used by the Runtime API.
  • defaults holds settings inherited by everything below it, most importantly the mode, http or tcp, and the timeouts. Missing timeouts are a classic cause of connections piling up, and HAProxy warns about them when it starts.
  • frontend describes what HAProxy listens on: addresses, ports, certificates and the rules that decide which backend receives each request.
  • backend lists the servers behind the balancer, how traffic is spread among them and how their health is checked.

After every edit, haproxy -c -f /etc/haproxy/haproxy.cfg checks the file before you reload. A reload through systemd starts new processes with the new configuration while existing connections finish on the old ones.

An HAProxy config example, in words

A common layout for a business website with two application servers looks like this:

  • A frontend binds port 80 and redirects every request to HTTPS, and binds port 443 with ssl and a crt directory that holds the certificates.
  • Rules in the frontend send requests whose path begins with /api to an API backend and everything else to the web backend.
  • Each backend has a balance line, an HTTP health check and two server lines, each with the check keyword.
  • The frontend adds the X-Forwarded-For header with option forwardfor and sets X-Forwarded-Proto, so the application logs real visitor addresses and knows the original request used HTTPS.

That last point is easy to miss. Without those headers, applications behind the balancer see every visitor as coming from HAProxy's own address, and some create redirect loops because they believe the request arrived over plain HTTP.

Choosing a load balancing algorithm

  • roundrobin, the default, takes turns and respects server weights. Good for short, similar requests.
  • leastconn sends new connections to the server with the fewest active ones. Better when requests vary widely in duration, such as reports, uploads or long-lived connections.
  • source, or a hash of a header or URL, keeps the same client or resource on the same server. Useful for caches, less so for spreading load evenly.

Weights let a larger server take a bigger share, and a weight of zero keeps a server configured without sending it new requests.

HAProxy health check settings that reflect reality

The check keyword on its own only tests that a TCP port answers, which a crashed application behind a running web server still does. An HTTP HAProxy health check asks for a real page: option httpchk together with http-check send and http-check expect lets you request a path such as /health and require status 200. A good health endpoint touches the dependencies that matter, such as the database, without being expensive to run.

Timing is set per server: inter for the interval, fall for how many failed checks mark a server down and rise for how many successes bring it back. Checks that are too aggressive take healthy servers out during a brief slowdown; checks that are too slow keep sending visitors to a dead server. Health checks are one of the first things we review in an existing HAProxy load balancer setup.

HAProxy sticky sessions and HAProxy SSL termination

If the application keeps logins or carts in local files or memory, a visitor who lands on a different server loses their session. The best fix is in the application: store sessions in a shared place such as Redis or the database. Where that is not possible, HAProxy sticky sessions use a cookie directive in the backend, for example cookie SERVERID insert indirect nocache, and a cookie value on each server line. HAProxy then pins each visitor to one server and moves them only if that server fails.

HAProxy SSL termination means HAProxy handles TLS and passes plain HTTP to the servers over a private network. That keeps certificates in one place and lets HAProxy read requests for routing. If the path between HAProxy and the backends crosses networks you do not control, encrypt that leg as well by adding ssl and certificate verification to the server lines.

Drain a server with the HAProxy Runtime API

For a zero-downtime deployment, take one server out of rotation, update it, check it and put it back. The HAProxy Runtime API does this without editing the file. Through the admin socket defined in the global section, a command such as set server web/app1 state drain stops new visitors from reaching app1 while existing sessions finish, and state ready returns it to service. Deployment scripts can drain a server this way, wait until its connection count reaches zero and then continue. Changes made through the socket are not written to the configuration file, so permanent changes still belong there.

The same socket, and the built-in statistics page, show every server's state and health check results; restrict both to administrators. Every directive and command is described in the official HAProxy documentation, organized by version.

Frequently asked questions: haproxy configuration

Can one HAProxy handle websites and other services?

Yes. One configuration can balance websites in http mode and services such as databases or mail in HAProxy TCP mode, each with its own frontend and backend. In TCP mode HAProxy passes connections through without reading them.

Which HAProxy version should we run?

A long-term support branch, such as 3.2, for production. Distribution packages often trail the current branches, so check which version your server actually installs; the HAProxy project lists its maintained branches and points to newer packages for Debian and Ubuntu.

How many servers do we need behind HAProxy?

At least two for redundancy, each able to carry peak traffic on its own. Otherwise draining one for a deployment, or losing one to a failure, overloads the other at exactly the wrong moment.

Planning a load balancer, or want a second pair of eyes on an existing configuration? Our HAProxy load balancer installation and configuration service covers health checks, TLS termination and failover planned around your application, for businesses in Los Angeles and beyond. The backends usually need attention too; see our Apache web server optimization service. Contact us with a short description of your servers and traffic.