Load Balancer Setup with HAProxy: Distributing Traffic Safely
AI generated
$
/etc
Linux · High Availability · Clustering · Load Balancing
Load Balancer Setup with HAProxy
Distribute traffic, remove unhealthy servers automatically

A single application server does not scale indefinitely and goes offline instantly on failure. HAProxy distributes requests across multiple backend servers, automatically detects failed instances through health checks, and turns several individual servers into a resilient, horizontally scalable unit.

19 min read Backends · Health Checks · Sticky Sessions · SSL Termination HAProxy 2.x · Linux

1. Why a load balancer like HAProxy is needed

HAProxy is one of the most widely used software load balancers in the Linux world and solves two problems at once: scaling and failure resistance. A single application server has a fixed upper limit on concurrent connections and CPU capacity, no matter how well the application itself is optimized. Once that limit is reached, the only real fix is distributing traffic across multiple servers instead of continually sizing up a single one.

At the same time, a single application server is also a single point of failure. If it goes down, the service is completely offline, even if the application itself runs flawlessly. This is exactly where HAProxy comes in: it distributes incoming requests across a group of backend servers using configurable algorithms and automatically removes any server from rotation that stops responding to a health check. Clients notice nothing, they still address only a single endpoint.

In typical PHP and Magento setups, HAProxy sits in front of multiple identically configured application servers that all access the same session storage and the same database. This enables horizontal scaling: when load increases, another application server is added and registered in the HAProxy configuration, with no downtime or application change required. The following sections walk through the entire path from installation to a production ready setup with SSL and monitoring.

2. Architecture: frontend, backend and ACLs

The HAProxy configuration file, located by default at /etc/haproxy/haproxy.cfg, is divided into clearly separated blocks. A frontend block defines on which port and protocol HAProxy accepts requests, while a backend block contains the list of actual target servers requests get forwarded to. This strict separation allows a single frontend to be coupled to several different backends, depending on rules such as URL path or host header.

Access Control Lists, or ACLs, are the tool used to make these routing decisions. An ACL checks a condition, for example whether the path starts with /api/, and routes into a specific backend based on the result. This lets a single HAProxy instance distribute both static content and dynamic PHP traffic to different backend groups, without needing two separate load balancers.

Another important building block is the defaults block, where shared timeout values, logging options and mode (http or tcp) are centrally set for all subsequent frontend and backend blocks. This structure keeps HAProxy configurations manageable even with many backends, because recurring settings do not need to be redefined in every block.

3. Installation and a first haproxy.cfg

Installing HAProxy happens via the distribution's package manager, though newer versions are often obtained through additional repositories to benefit from features such as improved HTTP/2 support. After installation, haproxy -c -f /etc/haproxy/haproxy.cfg validates the configuration for syntax errors before the service is restarted, which should become mandatory before every deployment in production environments.


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

# Install HAProxy on RHEL/AlmaLinux
sudo dnf install -y haproxy

# Validate configuration syntax before reloading (always run this first)
sudo haproxy -c -f /etc/haproxy/haproxy.cfg

# Reload without dropping active connections
sudo systemctl reload haproxy

# Enable on boot
sudo systemctl enable haproxy

# /etc/haproxy/haproxy.cfg — minimal working configuration
global
    log /dev/log local0
    maxconn 4096
    user haproxy
    group haproxy

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

frontend web_front
    bind *:80
    default_backend app_servers

backend app_servers
    balance roundrobin
    option httpchk GET /healthz
    server app1 10.0.0.11:80 check
    server app2 10.0.0.12:80 check
    server app3 10.0.0.13:80 check

This minimal setup accepts HTTP requests on port 80 and distributes them round robin across three backend servers, with check enabling an active health check for every server. Even with this small amount of configuration, a working load balancer is already operational, which is then extended with balancing strategy, SSL and monitoring.

4. Balancing algorithms compared

HAProxy supports several distribution algorithms, each better suited to different use cases. roundrobin distributes requests evenly in turn across all available servers and works well when all backend servers are roughly equally capable and requests generate similar load. leastconn, on the other hand, sends every new request to the server with the currently lowest number of open connections, which distributes load more fairly for long lived connections or heavily varying request durations.

The source algorithm consistently routes requests to the same server based on a hash of the client IP address, which enables a simple form of session persistence without cookies, but becomes problematic when many clients share the same IP behind a common NAT gateway. For weighted distribution, for instance when one backend server has more powerful hardware, every algorithm can additionally be given a weight parameter per server that controls the relative share of traffic.

Algorithm How it works Best suited for
roundrobin Even distribution in turn Similar backends, short requests
leastconn To server with fewest active connections Long connections, uneven request duration
source Hash of client IP, consistent mapping Simple IP based persistence without cookies
uri Hash of the request path Cache friendly routing of identical URLs

5. Health checks and automatic server removal

The option httpchk setting enables layer 7 health checks, where HAProxy periodically sends a real HTTP request to every backend server and evaluates the status code. If a server responds with an error code or does not respond at all, HAProxy marks it as down after a configurable number of failed checks and automatically removes it from rotation, without any human intervention needed.

It is important to build a dedicated health check endpoint that reflects real application health, for instance testing a database connection, instead of just serving a static page. An endpoint like /healthz that responds with status code 503 on a failed database connection ensures HAProxy correctly removes a server even when the web server itself is still running but the application behind it no longer works.


backend app_servers
    balance leastconn
    option httpchk GET /healthz
    http-check expect status 200
    default-server inter 3s fall 3 rise 2

    server app1 10.0.0.11:80 check weight 100
    server app2 10.0.0.12:80 check weight 100
    server app3 10.0.0.13:80 check weight 50 backup

The parameter inter 3s defines the check interval, fall 3 the number of failed checks needed before removal and rise 2 the number of successful checks needed before recovery. The server flagged backup only receives traffic once all primary servers have failed, which works well for a cheaper emergency server that stays unused during normal operation.

6. Sticky sessions for stateful applications

When an application stores session data locally on the respective application server instead of a central session store such as Redis, every request from a client must consistently be routed to the same server. This technique is called a sticky session and is implemented in HAProxy via cookie based persistence, where HAProxy inserts an additional cookie into the response that identifies the assigned server.

Architecturally, a central session store in Redis or Memcached is almost always the better approach, since every backend server becomes stateless and HAProxy can freely switch between them without users losing their session. Cookie based sticky sessions remain a pragmatic solution for legacy applications where switching to central session storage is not possible in the short term.


backend app_servers
    balance roundrobin
    cookie SRVID insert indirect nocache
    option httpchk GET /healthz

    server app1 10.0.0.11:80 check cookie app1
    server app2 10.0.0.12:80 check cookie app2
    server app3 10.0.0.13:80 check cookie app3

7. SSL termination and layer 7 routing

A common use case for HAProxy is SSL termination: HAProxy accepts the encrypted HTTPS connection from the client, decrypts it, and forwards the request unencrypted or re encrypted to the backend servers. This centralizes certificate management in a single place instead of equipping every backend individually with certificates, significantly simplifying both certificate renewal and TLS configuration.

For layer 7 routing based on the host header or path, ACL rules in the frontend are used to distribute different domains or URL prefixes to different backend groups. This is especially useful when a single public IP address needs to serve multiple applications, for example a Magento shop under the main domain and a separate API under a subpath.


frontend web_front
    bind *:443 ssl crt /etc/haproxy/certs/mironsoft.pem
    mode http

    # Route based on URL path prefix
    acl is_api path_beg /api/
    use_backend api_servers if is_api
    default_backend app_servers

backend api_servers
    balance leastconn
    server api1 10.0.0.21:8080 check
    server api2 10.0.0.22:8080 check

backend app_servers
    balance roundrobin
    server app1 10.0.0.11:80 check
    server app2 10.0.0.12:80 check

8. Stats dashboard and monitoring

HAProxy ships with a built in stats dashboard, enabled via a dedicated port, that shows in real time the status of every backend server, current connection counts, error rates and response times. This dashboard is one of the fastest ways to immediately see, during a problem, which server is currently marked down or producing an unusual number of errors.

For automated monitoring, HAProxy also exposes a CSV export of the statistics through the same stats URL, which Prometheus, Grafana or custom scripts can consume. In production setups it is common to hide the stats port behind basic auth or an IP whitelist, since it would otherwise publicly expose detailed infrastructure information.


listen stats
    bind *:8404
    stats enable
    stats uri /stats
    stats auth admin:s3cr3tPassword
    stats refresh 10s

9. HAProxy compared to nginx and cloud load balancers

HAProxy specializes in pure load distribution and offers deeper control over balancing algorithms, health checks and layer 7 routing than generic web servers that can also be used as load balancers. Open source nginx offers similar core functionality but less detailed health check options, though often with the more familiar configuration syntax for teams already running nginx as a web server. Cloud native load balancers, in turn, take on the entire operational responsibility, at ongoing cost, and offer less granular control over individual balancing details.

Solution Strength Operational effort
HAProxy Detailed health checks, stats dashboard, layer 4/7 Self hosted, full control
nginx (open source) Familiar syntax, good reverse proxy integration Self hosted, simpler health checks
Cloud load balancer Managed, automatic scaling No self operation, ongoing cost

For teams with their own Linux infrastructure and a desire for precise control over balancing behavior, HAProxy often remains the preferred choice. Combined with keepalived for the failure resistance of the HAProxy instance itself, a fully redundant setup emerges without dependency on a single cloud provider.

Mironsoft

Linux infrastructure, load balancing and server automation

Should traffic spikes stop bringing a server to its knees?

We design and operate HAProxy load balancers for Magento and PHP infrastructures, including health checks, SSL termination and monitoring, so your shop stays reliable even during traffic spikes.

Load balancer setup

HAProxy configuration with a fitting balancing algorithm

SSL & routing

Centralized SSL termination and layer 7 routing rules

Monitoring

Stats dashboard integration into existing monitoring

10. Summary

HAProxy solves two problems in a single configuration file: horizontal scaling across multiple backend servers and failure resistance through automatically removing unhealthy servers from rotation. The clear separation between frontend, backend and ACLs makes even complex layer 7 routing across multiple applications manageable, while balancing algorithms such as roundrobin and leastconn offer fitting distribution strategies for different load profiles.

Health checks against real application endpoints instead of plain port checks ensure HAProxy only serves genuinely functional servers. SSL termination centralizes certificate management in a single place, and the built in stats dashboard provides immediate visibility into the state of every backend server. Combined with keepalived for the redundancy of HAProxy itself, a fully failure resistant distribution layer emerges for production Linux infrastructures.

Load Balancer Setup with HAProxy — The essentials at a glance

Frontend/Backend

Clear separation between accepting requests and target server list, controlled via ACLs for layer 7 routing.

Health checks

Real application endpoints instead of plain port reachability, with fall/rise against flapping.

Balancing

roundrobin for similar servers, leastconn for uneven connection duration.

SSL & monitoring

Centralized SSL termination, stats dashboard with basic auth for ongoing visibility.

11. FAQ: Load Balancer Setup with HAProxy

1HAProxy vs. nginx as a load balancer?
HAProxy is specialized for load distribution with detailed health checks. nginx offers similar core functionality with less granularity.
2Which balancing algorithm as default?
roundrobin for similar backends, leastconn for uneven request duration or long connections.
3How do I check real application health?
A dedicated /healthz endpoint should test critical dependencies and return 503 on problems.
4Sticky sessions needed with Redis sessions?
No, with central session storage backends are stateless, HAProxy can distribute freely.
5How does SSL termination work?
bind *:443 ssl crt terminates HTTPS in the frontend, centralizing certificate management.
6How do I monitor HAProxy?
Built in stats dashboard or CSV export for Prometheus/Grafana.
7HAProxy for non HTTP traffic?
Yes, with mode tcp at layer 4, for example database failover, without layer 7 features.
8What happens on total backend failure?
HAProxy responds with 503. A backup server can be defined as an emergency fallback.
9Is HAProxy itself a single point of failure?
Yes, without extra measures. Combining with keepalived for a redundant virtual IP solves this.
10Add a backend server without downtime?
Add a new server line, then systemctl reload haproxy. Existing connections remain unaffected.