Skip to main content

HAProxy on a VDS: Load Balancing and Health Checks

VDS / VPS Servers · 29.09.2026

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:

AlgorithmWorking principle
roundrobinCycles through each server in turn
leastconnSends to the server with the fewest active connections
sourceHashes 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 -c before reload.
  • Point httpchk at 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.
← Back to Knowledge Base Ask Support