Marcio Cunha

How to configure load balancing with HAProxy

Learn how to build a high-availability traffic balancer using HAProxy to distribute HTTP requests across multiple backend application servers.

Marcio Cunha•5 min
Also available in:PortuguêsEspañol
Summary
  • HAProxy acts as an intelligent traffic router that divides workloads among several backend computers.
  • Setting up health checks prevents the system from routing traffic to a crashed server.
  • Round-robin load balancing distributes incoming access sequentially and evenly across machines.
  • Adjusting timeouts prevents stuck connections from consuming precious infrastructure resources.
  • Keeping IP and port rules organized ensures the security and stability of the web environment.

What a load balancer is in practice

Imagine a large retail store with only a single cashier handling a gigantic line of customers. Slowness is inevitable and the system quickly collapses. To fix this, the manager opens several simultaneous cash registers and places a receptionist at the entrance whose sole job is to direct the next customer in line to whichever cashier is free. In computer architecture, this intelligent receptionist is called a load balancer. It sits at the front line receiving all user requests and intelligently distributes them among several servers running the same application behind the scenes.

When talking about modern web systems that need to handle thousands of simultaneous visits without crashing, relying on a single machine is a huge risk. If the main server fails, the entire website goes offline. Distributing traffic solves both performance and availability problems, because if one computer fails, the others keep responding. To manage this flow with maximum speed and low memory consumption, the most respected tool in the software engineering world is HAProxy. It is a lightweight and extremely fast software designed for this exact mission.

Before diving into setup, remember that configuring networks requires careful attention to ports and access, similar to how we need to unblock ports in the Windows firewall to allow proper communication between systems. HAProxy will occupy the main entry port, usually port 80 for HTTP or 443 for HTTPS, bridging traffic to the internal servers on the private network. It does not process the application itself; its job is purely logistical: receive, check the destination, choose the best server, and forward the request.

Installing and preparing the HAProxy environment

Installing HAProxy on Linux-based operating systems, such as Ubuntu or Debian, is quite straightforward and uses the distribution's standard package manager. In practice, this means opening the terminal of the server that will act as the gateway for your infrastructure and running the installation commands. Before modifying any configuration files, it is always wise to ensure that the operating system has all packages updated to prevent dependency conflicts or known security vulnerabilities.

To perform a quick installation on your Linux server, you can follow the steps below using the terminal with administrative privileges:

  1. Update the local package list by typing in the terminal
    sudo apt update
  2. Install the official HAProxy package by running
    sudo apt install haproxy -y
  3. Verify that the service started correctly with
    sudo systemctl status haproxy

Once the installation is complete, the main configuration file will be located at /etc/haproxy/haproxy.cfg. Inside this text file, we define the router's behavior, specifying which ports it should listen to and which internal IP addresses it should forward user traffic to. In more complex networks where we need to map static addresses or simulate test environments, it is also common to adjust domain name configuration files, much like the process of configuring the hosts file on Linux to redirect IPs during development.

Structuring the main configuration file

The heart of HAProxy is its configuration file, which is essentially divided into two main parts: the global section and the traffic rules. The global section defines system parameters, such as simultaneous connection limits and the operating system user that will run the process for security reasons. The frontend and backend sections are where the balancing magic actually happens. The frontend defines the visible face of the service, listening for incoming requests from the internet, while the backend lists the actual application servers hidden in the internal network.

To better understand the structure, imagine we need to configure HAProxy to receive access on port 80 and distribute it between two different web servers. A typical functional configuration block looks like the example below, which you can adapt to your real infrastructure scenario:

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

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

frontend web_front
    bind *:80
    default_backend web_servers

backend web_servers
    balance roundrobin
    server app1 192.168.1.10:8080 check
    server app2 192.168.1.11:8080 check

In this practical example, the balance roundrobin line instructs HAProxy to alternate requests sequentially: the first goes to server one, the second to server two, and the third goes back to server one. The check directive at the end of each server line is vital because it tells HAProxy to constantly monitor whether that computer is alive and responding. If server app1 crashes due to a power outage or hardware failure, HAProxy stops sending clients to it instantly, saving the user from encountering a generic error page.

Ensuring resilience and operational best practices

Configuring a load balancer is not just about making traffic flow; it is about ensuring the system is resilient against unexpected network failures or sudden access spikes. One of the most common pitfalls in high-availability environments is connection exhaustion due to slow clients taking too long to send or receive data. This is why the timeout parameters we placed in the defaults section of the configuration file are so important. They define the time limit HAProxy should wait before giving up on a stuck connection, freeing up resources to serve new users.

Furthermore, monitoring load balancing behavior in real-time helps identify bottlenecks before they affect the application's end users. HAProxy features a built-in statistics page that can be enabled in the configuration file, allowing you to view current traffic, requests per second, and the health status of each backend. Keeping this visibility layer organized and regularly testing network behavior ensures that your infrastructure remains solid, predictable, and ready to scale whenever the business needs to grow.