Understanding Load Balancers in System Design

One entrance, many servers

Imagine that an online shop becomes so popular that one computer cannot answer every visitor quickly enough. The team adds two more computers to share the work. But visitors still need one address to open the shop, and someone must decide which computer handles each request.

A server is a computer that receives a request and sends a response. A load balancer sits in front of several servers and sends incoming work to an available one. It helps the servers work together, but it cannot make each server do more work than it can handle.

What you’ll learn

  • Explain how one load balancer shares incoming requests between several servers.
  • Work out whether the remaining servers can keep up when one stops working.
  • Recognise which measurements matter when comparing real load-balancing products.

One entrance, healthy destinations

VisitorsOne public address
Load balancerSelect a healthy destination
Server AHealthy
Server BHealthy
Server CHealthy
Visitors use one shop address. The load balancer shares their requests between the shop’s available servers.

How does a request find a server?

One request, one healthy destination

VisitorsOne public address
Load balancerSelect a healthy destination
Server AHealthy4 open connections
Server BHealthy1 open connections
Server COffline · skipped

Round robin starts with A. C is offline, so it is excluded.

Connections stay open in this teaching illustration. Reset returns A to four and B to one.

The balancer sends each request to a selected destination. Health checks and the balancing policy influence that selection.

When you open the shop, your browser sends a request—for example, “show me the products.” The load balancer receives that request and chooses a server to answer it. The response then makes its way back to your browser.

One simple choice is round robin: send work to server A, then B, then C, and repeat. Another choice, least connections, prefers a server with fewer open connections. A connection is a communication channel between computers; fewer connections do not always mean less work, because some requests take longer than others.

The balancer regularly checks whether servers respond. If a server stops responding, it can stop sending new work there after detecting the problem. A request already on its way may still fail. Information such as a shopping basket should be accessible to whichever server handles the next request.

Go deeper: what can a balancer inspect?

A Layer 4 balancer selects a destination using transport connection information. A Layer 7 balancer understands application traffic such as HTTP and can make choices using a page path or request header. HTTP is the set of rules browsers and web servers use to exchange requests and responses.

Increase load. Lose a server.

Losing a server removes capacity

Incoming traffic: 1,200 requests/s

Server A500 requests/s
Server B500 requests/s
Server C500 requests/s
1,500Available requests/s
0Capacity shortfall/s

Three healthy servers provide 1,500 requests/s of assumed capacity, above the incoming 1,200.

Teaching assumptions, not a benchmark. Failure removes capacity even when routing still works.

These numbers belong to the lesson’s simplified model. Routing around a failed server does not replace its lost capacity.

Suppose each server can answer 500 requests in one second. Three servers can therefore answer up to 1,500 requests per second in this simplified example. This is their capacity: the amount of work they can handle in the time available.

Move the incoming-requests slider to change how much work arrives. Then select “Make one server unavailable”. A backend is simply a server behind the load balancer. Watch whether the remaining servers can keep up. “Pending growth” shows how much unfinished work could accumulate each second if excess requests are allowed to wait.

Try starting at 1,200 requests per second with three servers, then fail one. Can you explain why the remaining capacity is too small?

Backend capacity lab

Teaching simulation

These capacities are illustrative assumptions, not measured product benchmarks.

Use the assumptions above to compare incoming traffic with available capacity.

Which load balancers can you actually use?

Who looks after the load balancer?

Your serversHAProxy · NGINX · Envoy

Your team configures routing, maintains hosts and arranges recovery.

Hosting and staff time
Managed serviceAWS ALB

AWS operates the balancer. Your team configures it and keeps the application healthy.

Running and usage charges
Physical applianceF5 BIG-IP / rSeries

Your team operates hardware and software, with the support terms it purchases.

Hardware, licences, support
Deployment changes who maintains the infrastructure. Free software can still require hosting costs and staff time.

You do not need to buy an appliance to try load balancing. Some tools are free software that you run on your own computer or server. Others are paid software, cloud services or physical devices. The choice changes who installs, updates and looks after the load balancer.

Free software does not mean free hosting. Running a tool on a rented server still costs money. You also spend time on configuration, updates and monitoring. A paid product can include support or take over some of that work.

OptionFree or paid?Where it runs and why you might use it
HAProxy CommunityFree, open sourceOn your own computer or server. A focused tool for sharing traffic between servers; used in the local exercise next.
NGINX Open SourceFree, open sourceOn your own servers. Useful when a web server is already routing requests and serving files.
EnvoyFree, open sourceOn your own servers or within larger service platforms. Often used to manage communication between services; its configuration is more involved for a first exercise.
HAProxy Enterprise / NGINX PlusPaid commercial offeringsSoftware with vendor support and additional capabilities. Compare the offered features and support terms; request current pricing from the vendor.
AWS Application Load BalancerPaid managed serviceRuns in AWS. AWS operates the load-balancing service; you configure routing and your application servers. Billing includes running hours and usage-based capacity units. Rates depend on region and traffic.
F5 BIG-IP on rSeriesPaid hardware and softwareA physical appliance for your data centre. Compare hardware, software licences and support in the quote, alongside capacity and available network connections.

A practical starting choice: use HAProxy Community to learn the basic flow locally. If your application later lives in AWS and you want AWS to operate the load balancer, evaluate ALB. If you need vendor support on your own servers, compare the commercial software options. Your requirements decide the choice; a paid label does not by itself imply higher throughput.

These are representative choices, not every product available. Licensing and billing models were checked on 6 October 2026; follow the product links for current terms.

Explore real implementations

Capacity has several dimensions

Same workload, comparable conditions
Request rateHow many requests finish?
Data throughputHow much data moves?
ConnectionsHow many remain active?
Response timeHow long do visitors wait?
ReliabilityWhich requests fail?
Test conditionsCPU, network, TLS and payloads
A single large throughput number does not tell you whether a product meets your response-time and reliability requirements.

Verified 6 October 2026. These are representative implementations, not an exhaustive inventory. Product throughput depends on payloads, TLS, connection reuse, CPU, network and configuration.

Requests per second measures how much work gets done. Response time measures how long a visitor waits. A p99 response time describes a threshold that 99% of measured responses meet; the slowest 1% take longer. TLS is the encryption used to protect traffic, and setting up encrypted connections also uses resources.

  • HAProxy 3.4 documentation: software proxy with round-robin and least-connections policies. Benchmark requests/s, concurrent connections and p99 latency on your chosen host.
  • Envoy: programmable proxy and load-balancing policies. Its latest documentation may include development features; verify the deployed stable release.
  • AWS Application Load Balancer: managed HTTP routing. Quotas and capacity units describe different dimensions; they are not a universal requests/s guarantee.

A hardware appliance comparison must include licensed throughput, TLS transactions/s, interfaces, packet sizes and failover mode. A 10 Gbit/s interface has a raw upper bound of 1.25 GB/s before protocol overhead; application throughput can be much lower. The lab assumes 500 requests/s per backend for teaching only, not any product benchmark.

Compare software, managed services and hardware

Capacity evidence checked 6 October 2026. Vendor ceilings below are published specifications, not independent measurements or guaranteed performance for your workload.

ImplementationCapacity evidenceWhat to measure
HAProxy / Envoy / NGINXNo universal requests/s limit: host and configuration determine capacity.Requests/s at target p99; TLS handshakes/s; payload size; CPU and NIC saturation.
AWS ALBManaged capacity and account quotas. Evaluate connections, bytes and rule evaluations rather than treating one quota as throughput.Target latency, surge behaviour, quotas and cost under your traffic mix.
F5 r10000 seriesVendor publishes up to 6.6 million L7 requests/s and 190 Gbit/s L4/L7 throughput.Exact appliance/licence, TLS profile and enabled security features; validate with your payloads.
F5 r5000 seriesVendor publishes up to 3.3 million L7 requests/s and 95/85 Gbit/s L4/L7 throughput.Same conditions; request rate and byte throughput are distinct dimensions.

For a reproducible test, record software version, vCPU count, RAM, NIC speed, TLS/cipher, payload bytes, connection reuse, concurrency, test duration, error rate and p50/p95/p99. Report sustained results separately from bursts.

Three common load balancers in production

Three production front doors

HAProxy

ClientsHTTP or TCP
HAProxyDedicated routing
App AApp B

Your team operates the hosts.

NGINX

ClientsWebsite requests
NGINXServe files and route HTTP
Site filesApp A/B

Web serving and routing can share a front door.

AWS ALB

ClientsHTTP or HTTPS
AWS ALBManaged routing
App · Zone AApp · Zone B

Your application spans separate locations in one AWS region.

These sketches show typical roles. Availability Zones are separate locations within an AWS region; each setup still needs healthy application capacity.

Production means the system is serving real users. Let’s look more closely at three common choices: HAProxy, NGINX and AWS Application Load Balancer. They represent a dedicated software load balancer, a web server that also balances traffic, and a managed cloud service. This is a practical shortlist rather than a ranking by market share.

HAProxy: a dedicated traffic distributor

Imagine several application servers answering the same API requests. An API is a way for one program to ask another for information or an action. HAProxy sits in front of those servers and decides which healthy server should receive each request. It supports both HTTP web traffic and TCP connections, which can carry other kinds of application traffic. It offers balancing policies and active health checks that probe servers even when visitors are not sending requests.

What you take on: with the free Community version, your team runs the hosts, updates the software, configures checks and arranges another load balancer for failover. It is a useful candidate when traffic routing is the main job and you want control over it. Official HAProxy overview · Configuration reference.

NGINX: web serving and load balancing together

A website may need to serve images and stylesheets as well as forward requests to application servers. NGINX can do both. Its HTTP load balancer supports round robin and least connections, so it can share application requests while also acting as the website’s front door.

What you take on: you still operate the hosts and configure recovery. In NGINX Open Source, passive checks can mark a server unavailable after configured request failures. Periodic active HTTP health checks are a commercial feature; do not assume that Open Source and NGINX Plus offer identical capabilities. If your team already runs NGINX, extending that setup may be simpler than introducing another tool. HTTP balancing guide · Server groups and failure handling.

AWS ALB: AWS operates the load-balancing service

Application Load Balancer, usually shortened to ALB, routes HTTP and HTTPS requests to application targets in AWS. A target is a destination that can answer a request. Rules can send /images and /orders to different groups of servers. You configure targets, health checks and routing; AWS operates the load-balancing infrastructure.

What you take on: you pay running and usage charges, work within AWS service limits, and still keep your application servers healthy. Spread the application across Availability Zones—separate locations within an AWS region—to reduce exposure to a location failure. ALB removes host maintenance for the balancer, but it does not automatically fix the application. ALB features · Deployment guide · Pricing.

Capabilities checked on 6 October 2026. Next, use requirements to decide which of these approaches fits a particular system.

Choose a load balancer from the requirements

Let the requirements guide the choice

HAProxy

Your hosts + HTTP/TCP + active checks

You configure and operate redundant balancers.

AWS ALB

AWS + HTTP/HTTPS + less host upkeep

Usage charges and AWS-specific configuration.

AWS NLB

AWS + connection-level TCP traffic

Different routing layer; no HTTP path rules.

For the existing NGINX website scenario, NGINX is a useful starting choice. Compare operating needs and measured results before deciding.

These are starting points for the scenarios below. Protocols, operating skills and measured results can change the decision.

There is no winner for every system. Start with where the application runs, what traffic it receives, who will maintain it, and what happens during a failure. The choices below are reasoned starting points for the stated requirements, not measured performance rankings.

1. A small website already uses NGINX

Requirements: two rented application servers, website images and stylesheets, a small budget, and a team comfortable maintaining NGINX.

Start with NGINX Open Source. It can serve files and balance HTTP requests in the setup the team already understands. Adding HAProxy might create another system to maintain without meeting a new need. Trade-off: the team owns updates and failover, and must check whether passive failure detection meets its needs. If periodic active HTTP checks or vendor support are required, compare NGINX Plus with HAProxy instead.

2. A team needs dedicated routing on its own servers

Requirements: servers in the team’s own data centre, both web requests and TCP connections, active checks, and staff who can operate redundant load balancers.

Start with HAProxy. Its dedicated routing role and HTTP/TCP support fit those needs without requiring a cloud move. NGINX may also fit some workloads, but serving website files is not part of this requirement. Trade-off: HAProxy Community avoids a software licence fee while leaving configuration, monitoring and recovery with the team. Compare commercial support if staff need help operating it.

3. An AWS web application has a small operations team

Requirements: HTTP/HTTPS traffic, separate routes for catalogue and checkout, application servers across two Availability Zones, and little time to maintain load-balancer hosts.

Start with AWS ALB. Its request-routing rules and managed infrastructure match the hosting environment and reduce host maintenance. Self-hosted HAProxy or NGINX may offer more configuration control, but the team would have to operate them. Trade-off: ALB adds ongoing usage charges and AWS-specific configuration. Compare the full operating cost, including staff time; a free software licence alone does not settle the decision.

4. The traffic is not HTTP

Requirements: a custom application uses long-lived TCP connections rather than website requests.

ALB is not the right fit for this traffic. Evaluate HAProxy’s TCP mode if the team wants to run its own load balancers. In AWS, also evaluate Network Load Balancer (NLB), a different service that handles connection-level traffic. Trade-off: connection routing does not provide ALB’s HTTP path rules. Check protocol support, connection duration, address requirements and operating cost before choosing.

Check capacity before accepting any choice

Suppose peak traffic is 2,500 requests per second. In a teaching example, each application server sustains 1,500 requests per second at an acceptable response time. Two servers handle the peak together, but only 1,500 requests per second remain if one fails. Three servers leave 3,000 requests per second after one failure, provided their shared database and other dependencies can keep up. These numbers are assumptions, not product specifications.

Choosing a different load-balancer brand does not repair that capacity gap. Test your chosen balancer and application together with realistic request sizes, encrypted connections, latency targets and a failed server. Revisit the choice if the measurements or the team’s operating needs change.

Try a real load balancer on your computer

Your computer, three containers

Your terminalcurl 127.0.0.1:8080
Docker’s internal network
HAProxy :8080Only published host port
app_a :8000Replies “Server A”
app_b :8000Replies “Server B”

Backend ports stay inside this network.

The two web servers are reached through HAProxy. Their own ports are available inside the lab’s Docker network.

This optional exercise runs one HAProxy load balancer and two tiny web servers. Each server returns its own name, so you can see which one answered. You do not need a cloud account, and you can complete the lesson without running this exercise.

You need a running Docker installation with Docker Compose and an unused local port 8080. Docker runs the three programs in separate containers, which are isolated processes that can communicate on a shared network. The first start downloads their images from the internet. HAProxy is free software; Docker Desktop has separate licensing terms.

Download the complete local lab (.zip). Unzip it and open a terminal in the load-balancer-lab folder. The included README contains the full sequence and cleanup command.

The folder contains compose.yaml, haproxy.cfg and two folders named server-a and server-b. Each server folder contains an index.html file that says either Server A or Server B.

See how the three programs are connected

compose.yaml starts the programs and connects them. Only HAProxy publishes a port on your computer. The two application servers are reached through the internal network.

services:
  balancer:
    image: haproxy:3.4.6
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
    depends_on:
      - app_a
      - app_b
  app_a:
    image: python:3.13.16-alpine
    command: ["python", "-m", "http.server", "8000", "--directory", "/site"]
    volumes:
      - ./server-a:/site:ro
  app_b:
    image: python:3.13.16-alpine
    command: ["python", "-m", "http.server", "8000", "--directory", "/site"]
    volumes:
      - ./server-b:/site:ro

The image versions are pinned to stable releases checked on 6 October 2026. See the official HAProxy image and Python image documentation.

HAProxy reads this configuration. The frontend accepts your requests at port 8080. The backend lists the servers that can answer. roundrobin shares new requests between healthy servers in turn.

defaults
  mode http
  timeout connect 5s
  timeout client 30s
  timeout server 30s

frontend local_shop
  bind :8080
  default_backend shop_servers

backend shop_servers
  balance roundrobin
  server a app_a:8000 check inter 1s fall 2 rise 2
  server b app_b:8000 check inter 1s fall 2 rise 2

Validate the Compose file, then start all three programs:

docker compose config
docker compose up -d

Now check that HAProxy accepts its configuration:

docker compose exec balancer haproxy -c -f /usr/local/etc/haproxy/haproxy.cfg

If startup fails, use docker compose logs to see the messages. If port 8080 is occupied, change the host port in the Compose file to 127.0.0.1:8081:8080 and use 8081 in the requests below.

Send requests, stop a server and try again

Before, during and after a server failure

1

Both healthy

Server AHealthy
Server BHealthy

A and B receive requests.

2

B stops

Server AHealthy
Server BChecking

Detection is pending. A request can fail.

3

Failure detected

Server AHealthy
Server BUnavailable

New requests go to A.

4

B passes checks

Server AHealthy
Server BHealthy again

A and B receive requests again.

Stage 1: both servers are healthy. New requests can go to A or B.

Step through the sequence. These stages show the order of events, not a measured detection time.

Detection takes time. A request during the transition can fail; the lab demonstrates recovery rather than an instant switch.

With the programs running, send a request through HAProxy:

curl http://127.0.0.1:8080/

Run that command several times. You should see Server A and Server B take turns responding while both are healthy. Each new curl command creates a new connection, making the round-robin behaviour easier to observe than repeated browser refreshes.

Now predict the result: if Server B stops, should visitors still receive an answer? Stop it and wait about three seconds for the health checks to notice:

docker compose stop app_b

Repeat the curl command. After failure detection, only Server A should answer. A request during the transition can fail. Here, HAProxy checks once per second and marks a server unavailable after two failed checks. These checks test whether a connection opens; they do not prove that an application can complete an order.

Bring Server B back, wait a few seconds, and repeat the requests:

docker compose start app_b

Once it passes two checks, both servers should answer again. You have now seen real request routing and failure detection, rather than just a capacity simulation.

Finish by stopping and removing the exercise containers:

docker compose down

This small exercise does not measure maximum throughput. It also uses one load balancer, so the load balancer itself is still a single point of failure. A production design needs to consider that failure too.

Choose connection routing or application routing

See the responsibility

Connection routingAddresses and ports
HTTP routingHostnames and paths
TLS boundaryChosen termination and next hop
ApplicationTrusted identity and permission rules
Connection routing: Addresses and ports → HTTP routing: Hostnames and paths → TLS boundary: Chosen termination and next hop → Application: Trusted identity and permission rules

A layer-4 balancer chooses a destination using connection information such as addresses and ports. A layer-7 balancer understands an application protocol such as HTTP and can route using a hostname or path. These are different capabilities; neither layer is automatically best for every workload.

For a shop, /images and /checkout might need different HTTP backends. For a generic TCP service, connection routing may be enough. Decide where TLS terminates and whether the next hop also needs encryption. Connections, requests, bytes, handshake cost and routing rules all affect capacity.

If a trusted proxy adds client-address headers, the application must accept them only under a deliberate trusted-proxy policy. Do not treat arbitrary client-supplied forwarding headers as authenticated identity. See protocols and proxies for the connection boundary.

Make a design decision

Three healthy servers handle 500 requests/s each. Traffic is 1,200 requests/s. One server fails. What changes?
Choose one answer. You can try again.

Answer and explanation

The remaining pool is short by 200 requests/s.

Two servers supply 1,000 requests/s. Pending work grows by 200 requests/s unless traffic is rejected or reduced.

Check the added design rule

Requests for /images and /checkout need different HTTP backends. Which capability matches that requirement?
Choose one answer. You can try again.

Answer and explanation

Application-aware routing, such as layer-7 HTTP rules.

The requirement depends on HTTP path information.

What to remember

A dependable entrance needs three things

A dependable entranceThe entire request path matters

Healthy destinations

Check that application servers can do the work users need.

Spare capacity

Keep enough headroom for peak traffic and a failed server.

Balancer recovery

Plan how traffic continues if the load balancer itself fails.

A load balancer is one part of the design. Healthy destinations, capacity headroom and balancer recovery make the whole path dependable.

A load balancer gives visitors one entrance and shares their requests among available servers. It can avoid a failed server after detecting the failure, but it cannot replace that server’s lost capacity.

Leave enough spare capacity for a busy period or a server failure. When evaluating a real system, measure both how many requests it handles and how long visitors wait for a response. The balancer itself also needs a plan for failure.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: CDN (Content Delivery Network) →