HAProxy’s maxconn setting, often perceived as a simple connection limit, fundamentally dictates how many concurrent connections a specific frontend or backend can accept and process, rather than just the total number of connections it can hold.

Let’s see it in action. Imagine a busy e-commerce site using HAProxy to distribute traffic to two backend web servers.

frontend http_in
    bind *:80
    mode http
    default_backend web_servers
    maxconn 1000  # This is our focus

backend web_servers
    mode http
    balance roundrobin
    server web1 192.168.1.10:80 check
    server web2 192.168.1.11:80 check

In this setup, the frontend http_in is configured with maxconn 1000. This means that the HAProxy frontend will stop accepting new incoming connections once it has 1000 active connections that it’s currently managing. It doesn’t mean the backend servers will be overloaded; it means HAProxy itself will start rejecting new requests if it’s already busy with 1000 connections.

The problem HAProxy solves is precisely preventing the backend servers from being overwhelmed by too many concurrent requests that they can’t handle. By setting maxconn on the frontend, HAProxy acts as a gatekeeper. When the connection count reaches maxconn, HAProxy will immediately return a 503 Service Unavailable error to new clients attempting to connect, rather than forwarding those new requests to the backend. This protects the backend servers from a sudden surge of traffic that could cause them to crash or become unresponsive.

The mental model here is that maxconn is a hard limit on HAProxy’s ability to accept new work. It’s not just a passive counter; it actively influences HAProxy’s behavior. When maxconn is reached, HAProxy stops initiating new connections to its backends for incoming client requests. Existing connections are unaffected and will continue to be processed until they complete or are closed.

The precise levers you control are the maxconn value on the frontend and, critically, the maxconn value on the backend servers within HAProxy’s configuration.

frontend http_in
    bind *:80
    mode http
    default_backend web_servers
    maxconn 1000

backend web_servers
    mode http
    balance roundrobin
    server web1 192.168.1.10:80 check maxconn 500  # Backend limit for web1
    server web2 192.168.1.11:80 check maxconn 500  # Backend limit for web2

Here, the frontend maxconn of 1000 is the aggregate limit. The individual backend server maxconn values (500 each) represent the maximum number of connections that HAProxy will try to establish to that specific backend server. HAProxy will distribute incoming connections to the backends, respecting both the frontend’s overall limit and each backend’s individual limit. If the frontend reaches 1000 connections, it stops accepting new ones. If, however, HAProxy has 800 connections active and the next request would push web1 over its maxconn 500 limit, HAProxy will try to send it to web2. If web2 is also at its maxconn 500 limit, the connection will be rejected by the frontend (even if the frontend itself hasn’t hit its 1000 limit yet).

The most common mistake people make is setting maxconn too high on the frontend and not considering the aggregate capacity of the backends. If your frontend maxconn is 2000, but your two backend servers can each only handle 500 connections concurrently (meaning HAProxy should have maxconn 500 on each backend server definition), HAProxy will happily try to push up to 1000 connections to the backends. It’s only when the backend server’s maxconn is hit that HAProxy will start rejecting connections even if the frontend’s maxconn hasn’t been reached. This distinction is crucial for understanding load distribution and prevention of overload. The frontend maxconn is a ceiling for HAProxy itself; the backend maxconn is a ceiling for how much work HAProxy will delegate to a specific backend instance.

When you tune maxconn, you’re essentially setting the appetite for new work at different stages of the request lifecycle. The frontend maxconn is the initial gate, and backend maxconn values are the granular controls for how much load each individual downstream service can absorb.

The next logical step after tuning maxconn is to investigate connection timeouts and their interaction with maxconn.

Want structured learning?

Take the full Haproxy course →