What HAProxy is and when you need it on a VDS
HAProxy is a TCP/HTTP load balancer and proxy that distributes incoming requests across multiple backend servers. It sits in front of a pair of web servers, a PHP-FPM cluster, or several application instances so the setup survives the failure of one node and traffic gets spread evenly. HAProxy was built from the start specifically as a load balancer and can monitor backend health deeply — there is a separate article on Nginx as a load balancer for a lighter option.
HAProxy is useful when a VDS, or several VDS instances, run more than one copy of an application and you need to decide where to route each request, as well as automatically remove failed servers from rotation.
Installing HAProxy on Ubuntu and Debian
The HAProxy package is available in the standard repositories. Install it and check the version:
apt update
apt install haproxy -y
haproxy -v
The service registers with systemd right away. The main configuration file is located at /etc/haproxy/haproxy.cfg. Make a backup before any changes:
cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
Basic configuration: frontend and backend
HAProxy configuration is built from a frontend section (what to listen on) and a backend section (where to send traffic). A minimal working example for distributing HTTP traffic between two servers:
frontend http_front
bind *:80
default_backend http_back
backend http_back
balance roundrobin
server web1 10.0.0.11:80 check
server web2 10.0.0.12:80 check
The check parameter at the end of the server line enables an availability check for that backend — without it HAProxy never finds out the server is down and keeps sending traffic to it.
Backend health checks
By default, HAProxy checks the TCP connection to the backend's port every few seconds. For HTTP services, it is better to enable a check against a specific URL to tell an open port apart from an application that actually responds:
backend http_back
option httpchk GET /health
http-check expect status 200
server web1 10.0.0.11:80 check inter 3000 fall 3 rise 2
server web2 10.0.0.12:80 check inter 3000 fall 3 rise 2
The inter 3000 parameter sets the check interval to 3000 milliseconds, fall 3 is how many failed checks in a row remove a server from rotation, and rise 2 is how many successful checks bring it back.
Load balancing algorithms
The balance parameter in the backend section defines how requests are distributed. The main options:
| Algorithm | Working principle |
|---|---|
| roundrobin | Cycles through each server in turn |
| leastconn | Sends to the server with the fewest active connections |
| source | Hashes the client IP — the same client always reaches the same server |
For session-based applications without shared session storage, use source or balance leastconn with stick-table enabled, so a user does not lose their login when switching between backends.
Checking the configuration, reloading, and monitoring
Before applying a new configuration, always check the syntax — an error in the file brings down the entire balancer and blocks traffic to all backends at once:
haproxy -c -f /etc/haproxy/haproxy.cfg
systemctl reload haproxy
Production checklist:
- Always validate the config with
haproxy -cbeforereload. - Point
httpchkat a real application health endpoint, not just the site root. - Open the balancer's port in the firewall — see the article on configuring UFW on a VDS.
- Connect general server resource monitoring alongside HAProxy — see the article on VDS resource monitoring.
- Enable the HAProxy stats page (
stats enable) on a separate port to see backend status in real time.