Server Management (Unmanaged)

Mastering Load Balancing with HAProxy

By the Domain India teamPublished 9 min read
Knowledge base article
Contents (10 sections)

When one web server is no longer enough, or you cannot afford it going down, you put a load balancer in front of two or more servers. HAProxy is the free, open-source load balancer used by many of the busiest sites on the internet. This guide explains how load balancing works, installs HAProxy on a current Linux server, walks through a working configuration with HTTPS and health checks, and covers algorithms, monitoring and failover.

This guide is for your own server

HAProxy is installed on a server where you have root access, such as a VPS. It cannot be installed on shared hosting (cPanel, DirectAdmin, Webuzo or Windows), where the server configuration is managed for everyone on it.

Key takeaways

Install HAProxy from your distribution's packages on AlmaLinux, Rocky Linux, Ubuntu or Debian, then define a frontend that receives traffic on ports 80 and 443 and a backend listing your application servers with health checks. Round robin suits identical servers and least connections suits long or uneven requests. Always test the configuration with haproxy -c before reloading, and protect the statistics page with a password.

1. What a load balancer does

A load balancer sits between visitors and your servers. Every request reaches the balancer first, and it forwards the request to one of several backend servers.

Spreads the load
No single server takes all the traffic, so each one stays responsive.
Survives failures
Health checks take a broken server out of rotation automatically.
Allows zero-downtime work
Drain one server, update it and put it back while the others serve visitors.

It does not make a slow application fast. If every request waits on the same overloaded database, adding web servers behind HAProxy will not help. Fix the bottleneck first; see Load balancing, web servers and database configuration for the wider architecture.

2. Layer 4 and layer 7 modes

HAProxy works in two modes:

ModeWhat HAProxy seesUse it for
mode http (layer 7)Full HTTP requests: hosts, paths, headers, cookiesWebsites and APIs; routing by path or domain, adding headers, HTTPS termination
mode tcp (layer 4)Only connections: IP addresses and portsDatabases, mail, or any non-HTTP service; HTTPS passed through untouched

Most websites use http mode, with HAProxy handling HTTPS so the backends can speak plain HTTP on a private network.

3. Install HAProxy

Use a supported distribution. CentOS Linux has reached end of life; AlmaLinux and Rocky Linux are the drop-in replacements.

bash
# AlmaLinux / Rocky Linux
sudo dnf install -y haproxy

# Ubuntu / Debian
sudo apt update && sudo apt install -y haproxy

haproxy -v                     # show the installed version
sudo systemctl enable --now haproxy

Distribution packages lag behind the newest release. For production, prefer an HAProxy LTS branch; if your distribution's version is old, use the official HAProxy package repositories for your distribution.

On AlmaLinux and Rocky Linux, SELinux blocks HAProxy from connecting to backends on unusual ports until you allow it, and firewalld must let web traffic in:

bash
sudo setsebool -P haproxy_connect_any 1
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --reload

4. A working configuration

The main file is /etc/haproxy/haproxy.cfg. This example terminates HTTPS, redirects HTTP to HTTPS and balances between two application servers on a private network.

haproxy
global
    log /dev/log local0
    maxconn 20000
    user haproxy
    group haproxy

defaults
    mode http
    log global
    option httplog
    option forwardfor
    timeout connect 5s
    timeout client  30s
    timeout server  30s

frontend web
    bind :80
    bind :443 ssl crt /etc/haproxy/certs/example.com.pem alpn h2,http/1.1
    http-request redirect scheme https code 301 unless { ssl_fc }
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    default_backend app

backend app
    balance leastconn
    option httpchk
    http-check send meth GET uri /health
    server app1 10.0.0.11:8080 check
    server app2 10.0.0.12:8080 check

listen stats
    bind 127.0.0.1:8404
    stats enable
    stats uri /stats
    stats auth admin:CHANGE-THIS-PASSWORD

What the parts do:

  • frontend is where visitors connect. It redirects plain HTTP to HTTPS and passes requests to the default backend.
  • backend lists your servers. check enables health checks, here a GET /health that your application should answer with status 200 only when it is really working.
  • option forwardfor adds the X-Forwarded-For header, so your application can see the visitor's real IP address.
  • listen stats serves the statistics page on localhost only. Reach it through an SSH tunnel rather than exposing it to the internet.

The certificate file for crt must contain the full certificate chain and the private key in one PEM file. If you use Let's Encrypt with Certbot, add a deploy hook that concatenates fullchain.pem and privkey.pem into that file and reloads HAProxy after each renewal.

5. Test and reload safely

  1. Check the syntax.
    Run sudo haproxy -c -f /etc/haproxy/haproxy.cfg. It must report the configuration as valid.
  2. Reload, do not restart.
    Run sudo systemctl reload haproxy. A reload starts new processes with the new configuration and lets existing connections finish.
  3. Watch the logs.
    Run sudo journalctl -u haproxy -f, or read the log file your syslog writes, while you send test requests.
  4. Test failover.
    Stop the application on one backend and confirm the stats page marks it DOWN and visitors still get answers.

6. Choosing a balancing algorithm

AlgorithmHow it choosesBest for
roundrobin (default)Each server in turn, respecting weightsIdentical servers and short requests
leastconnThe server with the fewest active connectionsLong or uneven requests, WebSockets, APIs
sourceA hash of the visitor's IP addressKeeping a visitor on one server without cookies
uriA hash of the requested pathCaching servers, so each path hits the same cache
randomA random server, optionally the better of twoLarge pools and frequently changing servers

Add weight to a server line to send more traffic to a bigger machine, for example server app3 10.0.0.13:8080 check weight 200.

Sessions: if your application keeps logins in local memory or files, a visitor bounced between servers will be logged out. The better fix is to store sessions in a shared database or Redis. If you cannot, add sticky sessions with a cookie:

haproxy
backend app
    cookie SRV insert indirect nocache
    server app1 10.0.0.11:8080 check cookie app1
    server app2 10.0.0.12:8080 check cookie app2

7. Monitoring and troubleshooting

  • Statistics page: shows each server's state, sessions, errors and response times in real time.
  • Logs: with option httplog, each line records timings and a termination state such as sD or SC that tells you whether the client, HAProxy or the server ended the connection.
  • Prometheus: current HAProxy versions include a built-in Prometheus exporter, so you can graph traffic and errors in Grafana.
  • Common error codes: 503 means no backend server is available (check your health checks); 504 means a backend was too slow (check timeout server and the application).

8. Removing the load balancer as a single point of failure

A single HAProxy server is itself a single point of failure. The usual answer is two HAProxy servers with keepalived, which uses VRRP to move a shared virtual IP address to the standby server if the active one fails. This needs an IP address that can move between servers, so check with your server provider before you design around it. Keep both HAProxy servers' configuration identical, for example with a configuration management tool such as Ansible.

Secure the balancer first

The load balancer is the front door to everything behind it. Keep it updated, allow SSH by key only, expose only ports 80 and 443, and keep the stats page and backends on private addresses.

9. Running HAProxy on Domain India

HAProxy needs a server you control. A Domain India VPS is self-managed: you get full root access and can choose a Linux distribution such as AlmaLinux, Rocky Linux, Ubuntu or Debian, and you are responsible for installing, securing and updating everything on it. You need at least three servers for a load-balanced setup: one running HAProxy and two application servers, or more for redundancy. If your servers talk to each other over public IP addresses, use each application server's firewall to accept traffic on the application port only from the HAProxy server's IP address. Ask support whether private networking between your VPSs is available before you plan around it.

If you only need to run one application and do not want to manage servers at all, the App Platform runs it for you; it does not give you your own HAProxy configuration.

VPS Starter
₹552.65/mo + GST
  • 1 vCPU
  • 2 GB DDR4 RAM
  • 64 GB NVMe SSD Storage
  • 2 TB Monthly Bandwidth
See plan details

Frequently asked questions

What is HAProxy used for?

HAProxy is a free, open-source load balancer and reverse proxy. It spreads HTTP or TCP traffic across several backend servers, removes failed servers automatically with health checks, and can handle HTTPS in front of your applications.

Can I install HAProxy on shared hosting?

No. HAProxy needs root access to a server, so it runs on a VPS or dedicated server that you manage. On shared hosting such as cPanel or DirectAdmin, the server configuration is managed for all customers and cannot be changed.

What is the default load balancing algorithm in HAProxy?

Round robin, which sends requests to each server in turn, adjusted by any weights you set. Least connections is usually better for long or uneven requests such as APIs and WebSockets.

How do I check an HAProxy configuration before applying it?

Run haproxy -c -f /etc/haproxy/haproxy.cfg. If it reports the configuration as valid, apply it with systemctl reload haproxy, which lets existing connections finish instead of dropping them.

Why does HAProxy return a 503 error?

A 503 means HAProxy has no healthy backend server to send the request to. Check the statistics page to see which servers are marked DOWN, then check that the health check path answers with status 200 and that the backend application is running.

How do I make HAProxy itself highly available?

Run two HAProxy servers with keepalived, which moves a shared virtual IP address to the standby server if the active one fails. This needs an IP address that can move between servers, so confirm that with your server provider first.

Ready to build a load-balanced setup? Compare VPS servers, or read about load balancing, web servers and database configuration.

Run HAProxy on your own VPS

Self-managed KVM VPS with full root access and your choice of Linux distribution, ready for HAProxy and your application servers.

See VPS plans

Ready when you are

Get VPS from ₹552.65/mo + GST

See plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app
HAProxy Load Balancing: Setup and Configuration Guide