Table of Contents
Role of HAProxy in Load Balancing
HAProxy is a high‑performance, open‑source TCP/HTTP load balancer and reverse proxy commonly used in front of web servers, APIs, and other TCP services. In the broader context of load balancing, HAProxy:
- Terminates client connections and forwards them to backend servers.
- Monitors backend health and avoids sending traffic to failed nodes.
- Offers flexible routing (by URL, header, SNI, source IP, etc.).
- Provides features for high availability, observability, and security controls.
Here we focus on its basic architecture, configuration model, and core concepts you must know to operate it.
Installation and Basic Concepts
Installing HAProxy
Commands vary by distribution; examples:
- Debian/Ubuntu:
sudo apt update
sudo apt install haproxy- RHEL/Fedora:
sudo dnf install haproxyService management (systemd-based systems):
sudo systemctl enable haproxy
sudo systemctl start haproxy
sudo systemctl status haproxy
The main configuration file is usually /etc/haproxy/haproxy.cfg.
HAProxy Process Model and Modes
Key ideas:
- Single binary, multiple roles: The one
haproxydaemon can: - Listen for client connections.
- Proxy them to backends.
- Provide statistics and admin interfaces.
- Layer 4 vs Layer 7:
- TCP mode (
mode tcp): Load balancing at transport layer; no awareness of HTTP. - HTTP mode (
mode http): Layer‑7 features like URL‑based routing, header manipulation, HTTP health checks. - Multi-process/thread support:
nbprocfor multiple processes (older approach).nbthreadfor multiple threads (modern recommended way).
These matter for performance tuning, but for fundamentals a single process with multiple threads is typical.
HAProxy Configuration Structure
All configuration is in haproxy.cfg. It is a declarative text file with sections:
global– process-wide settings (logging, max connections, tuning).defaults– default parameters applied tofrontend/backendsections.frontend– defines listener(s) that accept client connections.backend– defines groups of servers that receive proxied traffic.listen– combined frontend+backend in one block (useful for simple services).
A minimal skeleton:
global
log /dev/log local0
maxconn 4096
user haproxy
group haproxy
daemon
defaults
log global
mode http
timeout connect 5s
timeout client 50s
timeout server 50s
frontend http_in
bind *:80
default_backend web_servers
backend web_servers
balance roundrobin
server web1 10.0.0.11:80 check
server web2 10.0.0.12:80 checkGlobal Section Basics
Common global directives:
log– where to send logs (e.g. to syslog).maxconn– maximum concurrent connections.user/group– system user/group for the process.chroot– optional chroot directory for security.daemon– run in the background.nbthread– number of threads (e.g.nbthread 4).
Example:
global
log /dev/log local0
log /dev/log local1 notice
maxconn 10000
user haproxy
group haproxy
daemon
nbthread 4Defaults Section
Reduces repetition. Typical items:
mode– default protocol handling (httportcp).timeoutvalues –connect,client,server,http-request, etc.optionflags – e.g.option httplog,option dontlognull,option http-server-close.
Example:
defaults
log global
mode http
option httplog
option dontlognull
timeout http-keep-alive 10s
timeout connect 5s
timeout client 50s
timeout server 50sFrontends and Backends
Frontends: Entry Points for Clients
A frontend defines:
- Which address/port to bind to.
- Which protocol mode and logging style to use.
- Which backend to use by default.
- Optional ACLs and routing logic (covered briefly later).
Example HTTP frontend:
frontend public_http
bind *:80
mode http
# Basic logging options could be inherited from defaults
default_backend web_poolExample TCP frontend (e.g. for MySQL):
frontend mysql_front
bind 0.0.0.0:3306
mode tcp
default_backend mysql_poolThe `bind` Directive
bind chooses IP/port and encryption settings:
bind *:80– all interfaces on port 80.bind 192.168.1.10:443 ssl crt /etc/haproxy/certs/site.pem– HTTPS termination.
Multiple binds are allowed per frontend.
Backends: Pools of Destination Servers
A backend defines:
- The load‑balancing algorithm.
- The pool of servers.
- Health check settings.
- Optional per‑backend timeouts and connection options.
Example:
backend web_pool
mode http
balance roundrobin
option httpchk GET /health
server web1 10.0.0.11:80 check
server web2 10.0.0.12:80 checkTCP backend:
backend mysql_pool
mode tcp
balance leastconn
server db1 10.0.0.21:3306 check
server db2 10.0.0.22:3306 checkThe `listen` Section
For simple setups, listen combines frontend+backend:
listen stats
bind 127.0.0.1:9000
mode http
stats enable
stats uri /stats
For serious production configs, separate frontend and backend blocks give more flexibility and clarity.
Basic Load‑Balancing Algorithms
Select with balance in a backend.
Common algorithms:
roundrobin– rotate through servers one by one; default for HTTP in many setups.leastconn– send to server with fewest active connections; good for long‑lived connections.source– hash based on client IP; provides basic session stickiness per IP.uri/hdr(name)– hash on URL or header; useful for caching or app-specific sharding.
Example:
backend api_pool
mode http
balance leastconn
server api1 10.0.0.31:8080 check
server api2 10.0.0.32:8080 checkWeighted servers:
backend weighted_web
mode http
balance roundrobin
server web1 10.0.0.11:80 weight 1 check
server web2 10.0.0.12:80 weight 3 check
weight controls traffic share; in the above, web2 gets about three times as much traffic as web1.
Health Checks and Server States
Basic Health Checks
Health checks ensure traffic goes only to healthy servers.
- Add
checkto aserverline for basic TCP checks. - Use
option httpchkfor HTTP-level checks.
Example HTTP health check:
backend web_pool
mode http
option httpchk GET /health
http-check expect status 200
server web1 10.0.0.11:80 check
server web2 10.0.0.12:80 check
If a check fails repeatedly, HAProxy marks the server DOWN and stops sending it traffic until it recovers.
Server Line Options (Basics)
Useful per‑server options:
backup– only used if all non‑backup servers are down.maxconn– maximum connections for this server.rise/fall– how many successful/failed checks before changing state.slowstart– ramp up connections slowly after a server comes up.
Example:
backend web_pool
mode http
balance roundrobin
option httpchk GET /health
server web1 10.0.0.11:80 check rise 2 fall 3
server web2 10.0.0.12:80 check rise 2 fall 3 backupHTTP‑Specific Fundamentals
HTTP Mode and Logging
Using mode http enables:
- HTTP header inspection and modification.
- URL‑based routing.
- HTTP‑aware health checks.
For better logging, use:
defaults
mode http
option httplog
option dontlognull
This produces Apache‑style access logs via syslog (e.g. in /var/log/haproxy.log depending on your system).
Basic ACLs and Content Switching
ACLs (Access Control Lists) define conditions; you can route traffic based on them.
Example: route /api to api_pool, everything else to web_pool:
frontend public_http
bind *:80
mode http
acl is_api path_beg /api
use_backend api_pool if is_api
default_backend web_pool
backend api_pool
mode http
balance roundrobin
server api1 10.0.0.41:8080 check
server api2 10.0.0.42:8080 check
backend web_pool
mode http
balance roundrobin
server web1 10.0.0.11:80 check
server web2 10.0.0.12:80 checkExample: route by Host header (virtual hosts):
frontend public_http
bind *:80
mode http
acl blog_host hdr(host) -i blog.example.com
acl shop_host hdr(host) -i shop.example.com
use_backend blog_backend if blog_host
use_backend shop_backend if shop_host
default_backend default_webX‑Forwarded‑For and Proxy Headers
Since HAProxy sits between clients and backends, backends need to know the real client IP.
In HTTP mode, enable:
backend web_pool
mode http
balance roundrobin
option forwardfor
server web1 10.0.0.11:80 check
server web2 10.0.0.12:80 check
option forwardfor adds/updates the X-Forwarded-For header with the client IP.
Often combined with http-request set-header for additional headers:
backend web_pool
http-request set-header X-Forwarded-Proto https if { ssl_fc }Basic SSL/TLS Termination
HAProxy can terminate TLS and forward plain HTTP to backends (offloading CPU-heavy encryption).
In the frontend:
frontend https_in
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
mode http
default_backend web_poolNotes:
crtcan point to a single PEM file or a directory containing multiple PEMs.- For redirecting HTTP to HTTPS, you typically combine an HTTP frontend that issues a redirect with the HTTPS frontend that terminates TLS.
Basic HTTP → HTTPS redirect:
frontend http_in
bind *:80
mode http
http-request redirect scheme https code 301 if !{ ssl_fc }HAProxy Stats and Basic Monitoring
HAProxy includes a simple web-based stats interface and a socket for administration.
Enabling the Stats Page
Example:
listen stats
bind 127.0.0.1:9000
mode http
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:StrongPassword
Browse to http://127.0.0.1:9000/stats (from the host, or expose appropriately) to see:
- Frontend/backend states.
- Per‑server status (UP/DOWN), sessions, errors.
- Health check results.
Stats Socket (Basics)
A UNIX socket allows runtime operations (disable/enable servers, etc.). Minimal example:
global
stats socket /run/haproxy/admin.sock mode 660 level adminYou can then use:
echo "show stat" | socat /run/haproxy/admin.sock stdioFull use of the admin socket is more advanced, but knowing it exists is important for automation and fine‑grained control.
Managing Configuration and Reloads
Validating Configuration
Always validate before reloading:
sudo haproxy -c -f /etc/haproxy/haproxy.cfgIf there are syntax errors, HAProxy prints them without reloading the service.
Reloading Without Dropping Connections
On systemd distros:
sudo systemctl reload haproxyThis typically performs a graceful reload:
- Starts a new HAProxy process with the new config.
- Moves new connections to the new process.
- Allows existing connections to finish on the old process.
If your distro doesn’t support graceful reload by default, a common pattern is:
sudo service haproxy reload
(or an init script calling haproxy with -sf to send a soft-stop signal to the old process).
Putting It Together: Simple HTTP Load Balancer
An end‑to‑end example for a basic web setup:
global
log /dev/log local0
maxconn 5000
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5s
timeout client 50s
timeout server 50s
frontend http_in
bind *:80
mode http
# redirect to HTTPS
http-request redirect scheme https code 301 if !{ ssl_fc }
frontend https_in
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
mode http
# route /api to API servers, everything else to web servers
acl is_api path_beg /api
use_backend api_pool if is_api
default_backend web_pool
backend web_pool
mode http
balance roundrobin
option httpchk GET /health
option forwardfor
server web1 10.0.0.11:80 check
server web2 10.0.0.12:80 check
backend api_pool
mode http
balance leastconn
option httpchk GET /health
option forwardfor
server api1 10.0.0.21:8080 check
server api2 10.0.0.22:8080 check
listen stats
bind 127.0.0.1:9000
mode http
stats enable
stats uri /stats
stats auth admin:StrongPasswordThis demonstrates:
- Separate HTTP and HTTPS frontends.
- SSL termination.
- Different backends for web and API.
- Health checks and logging.
- A stats interface for monitoring.
Next Steps Beyond Fundamentals
Once comfortable with these fundamentals, typical progression includes:
- Advanced ACLs and routing rules.
- Sticky sessions and cookies.
- More complex SSL/TLS setups (SNI, OCSP stapling).
- TCP load balancing for databases, message queues, etc.
- High availability of HAProxy itself (e.g. with VRRP/keepalived).
- Integrating HAProxy logs with centralized logging and metrics systems.