Load Balancing
By the Syncfusion DevTutorials team · Last updated
Share traffic across many servers: scale up vs scale out, round robin, weighted and least connections, health checks, sticky sessions vs stateless servers, layer 4 vs layer 7.
Picture a busy supermarket during the evening rush.
There are four checkout lanes, and a staff member directs shoppers to one of them. If everyone is sent to the same lane, that lane becomes overloaded while the others remain underused. If shoppers are distributed evenly across all lanes, checkout times stay low and customers leave faster.
A load balancer works exactly like that staff member. It sits in front of your servers and decides which server should handle each incoming request.
The main idea: a load balancer distributes traffic across multiple servers and automatically avoids servers that are overloaded or unavailable.
What You Will Learn
In this lesson, you will learn:
- Why a single server is not enough for growing systems.
- The difference between scaling up and scaling out.
- What a load balancer does.
- Four common load-balancing algorithms.
- How health checks prevent traffic from reaching failed servers.
- Why sticky sessions are often a problem.
- The difference between Layer 4 and Layer 7 load balancing.
- How to avoid turning the load balancer into a single point of failure.
From Lesson 2, QuickBite must handle approximately 1,215 requests per second during lunch. Since a single server can process only about 500 requests per second, multiple servers are required, along with a mechanism to distribute traffic between them.
Why One Server Is Not Enough
A single server introduces two major risks.
Capacity Limits
Every server has a maximum amount of work it can handle.
Once that limit is reached:
- Requests become slower.
- Queues begin to form.
- Requests may eventually fail.
Single Point of Failure
If the server crashes, the entire application becomes unavailable.
Customers can no longer place orders, view menus, or track deliveries.
Scale Up vs Scale Out
There are two ways to increase capacity.
Scale Up (Vertical Scaling)
Make the existing server bigger by adding:
- More CPU cores.
- More memory.
- Faster storage.
Benefits:
- Simple to implement.
- No traffic distribution needed.
Drawbacks:
- Hardware has limits.
- The server still remains a single point of failure.
Scale Out (Horizontal Scaling)
Add additional servers and distribute requests among them.
Benefits:
- Capacity can continue growing.
- Individual server failures have less impact.
Drawbacks:
- Requests must be distributed intelligently.
Large internet systems generally prefer horizontal scaling.
As soon as multiple servers exist, something must decide where each request goes.
That component is the load balancer.
In simple terms: once you have multiple servers, you need a traffic controller.
What a Load Balancer Does
A load balancer performs three primary functions.
One Front Door
Clients communicate with a single address.
They do not need to know:
- How many servers exist.
- Which server handles their request.
- Whether servers are added or removed.
Traffic Distribution
The load balancer chooses a server and forwards each request.
Failure Avoidance
The load balancer continuously checks server health.
Unhealthy servers are removed from rotation until they recover.
Because users only interact with the load balancer, backend infrastructure can change without affecting customers.
Choosing a Server
The rule used to select a server is called a load-balancing algorithm.
Round Robin
Round Robin hands out requests in turn, like dealing cards: A → B → C → D → A → B → C → D. Step through eight requests:
Round Robin is simple and works well when:
- Servers are identical.
- Workloads are similar.
The limitation is that it assumes every server has the same capability.
The Wrong Way First: Round Robin with Uneven Servers
If one server is slower than the others, equal distribution creates problems.
Step through QuickBite sending 200 requests a second to three fast servers and one slow one:
| Server | Can handle | Round robin sends | Result |
|---|---|---|---|
| A, B, C | 100 a second each | 50 a second each | Fine |
| D | 40 a second | 50 a second | Queue grows by 10 every second |
The slower server accumulates a queue while faster servers remain underutilized.
This increases latency for customers assigned to that server.
Weighted Round Robin
Weighted Round Robin gives more traffic to stronger servers and less traffic to weaker servers.
Each server receives a weight based on its capacity.
The last two steps of the animation above show the fix, with weights of 100, 100, 100 and 40:
| Server | Weight | Share of 200 requests a second |
|---|---|---|
| A | 100 | 58.8 |
| B | 100 | 58.8 |
| C | 100 | 58.8 |
| D | 40 | 23.5 |
This keeps traffic proportional to server performance.
The challenge is maintenance.
Whenever server capacity changes, weights must also be updated.
Here is the same idea in code:
Weights give slow server D a smaller, safe share
const servers = [
{ name: "A", weight: 100 },
{ name: "B", weight: 100 },
{ name: "C", weight: 100 },
{ name: "D", weight: 40 },
];
const traffic = 200;
const totalWeight = servers.reduce((sum, s) => sum + s.weight, 0);
for (const s of servers) {
const share = (s.weight / totalWeight) * traffic;
console.log(`${s.name}: ${share.toFixed(1)} requests a second`);
}
Expected output:
A: 58.8 requests a second
B: 58.8 requests a second
C: 58.8 requests a second
D: 23.5 requests a second
Least Connections
Least Connections observes the current workload of each server.
New requests are sent to the server handling the fewest active requests.
Step through five new requests. Right now, A is working on 3 requests, B on 1, C on 4 and D on 2:
The code behind the animation:
Least connections always picks the shortest queue
// Requests each server is working on right now.
const open = { A: 3, B: 1, C: 4, D: 2 };
const picks = [];
for (let request = 1; request <= 5; request++) {
// Find the server with the fewest open requests.
const best = Object.keys(open).reduce((a, b) => (open[b] < open[a] ? b : a));
picks.push(best);
open[best] += 1; // it now has one more request in progress
}
console.log(`Picks: ${picks.join(" ")}`);
console.log(`Queues after: ${JSON.stringify(open)}`);
Expected output:
Picks: B B D A B
Queues after: {"A":4,"B":4,"C":4,"D":3}
The picks are B, B, D, A, B. Afterwards the queues are A 4, B 4, C 4 and D 3: nearly level.
This approach naturally adapts to differences in:
- Server speed.
- Request complexity.
- Temporary load spikes.
Servers that are already busy automatically receive fewer new requests.
For many web applications, this is an excellent default choice.
Random
Random selection chooses a server at random.
Advantages:
- Extremely simple.
- Low overhead.
Disadvantages:
- Does not account for server load.
- Does not account for server capacity.
A popular improvement is:
Pick two random servers, then choose the less busy one.
This often performs surprisingly close to Least Connections while remaining inexpensive.
Which Algorithm Should You Use?
| Method | Best For | Weakness |
|---|---|---|
| Round Robin | Identical servers and uniform traffic | Assumes equal capacity |
| Weighted Round Robin | Servers with known capacity differences | Requires manual tuning |
| Least Connections | Variable workloads and mixed server performance | Slightly more complex |
| Random | Simplicity and low overhead | Ignores server state |
Try It: Share the Lunch Rush
Experiment with different algorithms and traffic levels.
Notice that changing the balancing method can dramatically improve latency even when the hardware remains exactly the same.
Health Checks
Is the Server Healthy?
A load balancer periodically sends a request such as GET /health to each server.
This is called a health check.
Possible outcomes:
- Healthy → continue receiving traffic.
- Unhealthy → removed from service.
- Recovered → added back automatically.
Why Health Checks Matter
Without health checks, requests continue flowing to broken servers. Step through server D crashing, first without health checks and then with them:
Without health checks, the load balancer sends to A, B, C and D, so about 1 request in 4 fails. With health checks, it sends only to A, B and C.
Even a single failed server can generate a large number of customer-facing errors if health checks are disabled.
Good health checks verify critical dependencies as well. A server that responds "OK" but cannot reach the database may appear healthy even though every order request fails.
Sticky Sessions and Stateless Servers
What Are Sticky Sessions?
Suppose a user's shopping cart is stored in a specific server's memory.
Future requests must reach the same server or the cart appears empty.
One solution is sticky sessions, where the load balancer consistently routes a user to the same server.
Problems with Sticky Sessions
Uneven Traffic Distribution
Some users generate much more traffic than others.
If those users become attached to specific servers, those servers may become overloaded.
Scaling Becomes Difficult
Adding or removing servers can cause large groups of users to move to different servers.
Suppose the load balancer picks a server with user ID mod the number of servers. The figure shows users 1 to 12 before and after one of 4 servers is removed:
Removing one server of four moves 9 of these 12 users to a different server. Across 1,000 users, 749 move.
A large percentage of users are remapped even though only one server changed.
This can disrupt user sessions and create unnecessary load.
A Better Solution: Stateless Servers
Modern systems prefer stateless application servers.
Important user data is stored in:
- Databases.
- Shared caches.
- Session stores.
Any server can then handle any request.
Benefits:
- Easier scaling.
- Better fault tolerance.
- Simpler deployments.
In simple terms: application servers should not permanently remember individual users.
Layer 4 vs Layer 7 Load Balancers
Load balancers can operate at different networking layers.
Layer 4 Load Balancer
A Layer 4 load balancer examines:
- IP address.
- TCP/UDP port.
It does not inspect the request contents.
Benefits:
- Very fast.
- Very efficient.
Drawbacks:
- Cannot make routing decisions using URLs or application data.
Layer 7 Load Balancer
A Layer 7 load balancer can inspect:
- URLs.
- Cookies.
- Headers.
- Request paths.
Examples: Examples:
| Path | Sent to |
|---|---|
/menu | Menu servers |
/pay | Payment servers |
/admin | Admin servers |
| Benefits: |
- Intelligent request routing.
- Greater flexibility.
Drawbacks:
- Additional processing overhead.
Most modern web applications use Layer 7 load balancing because URL-based routing is extremely valuable.
Avoiding a Single Point of Failure
Imagine 20 healthy servers behind one load balancer.
If that load balancer fails, every request fails.
The application becomes unavailable despite healthy backend servers.
This makes the load balancer a single point of failure.
The solution is redundancy.
Production systems typically run:
- Multiple load balancers.
- Automated failover mechanisms.
- Highly available cloud-managed load balancers.
This ensures that one load balancer can fail without affecting customers.
Easy way to remember: one front door, many servers. The load balancer distributes traffic, avoids unhealthy servers, and always needs a backup front door.
Common Mistakes
| Mistake | Wrong | Correct | Why it happens |
|---|---|---|---|
| Round robin with uneven servers | Mixing an old slow server with new fast ones under plain round robin. | Use least connections, or set weights that match each server's speed. | Equal shares overload the slowest server, and its customers suffer. |
| No health checks | "The load balancer will figure it out." | Configure a health check URL and how many failures take a server out. | Without checks, a crashed server keeps receiving its full share of requests. |
| Keeping user data in one server | Storing carts in the memory of whichever server the user first reached. | Store carts and logins in a shared database or cache. | Otherwise, a restart or a new server loses customers' carts. |
| One load balancer | One load balancer in front of ten servers. | At least two load balancers, so one can take over if the other fails. | The ten servers do not help if the only front door is shut. |
| Watching only the average | "Average response time is 25 ms. All good." | "p99 is 1.5 seconds, and server D's queue is full." | One overloaded server hides inside a healthy-looking average. |
Practice
What to Remember
- Horizontal scaling is generally better than relying on one extremely large server.
- A load balancer acts as the single entry point for clients.
- Round Robin distributes requests evenly.
- Weighted Round Robin distributes requests proportionally to server capacity.
- Least Connections sends traffic to the least busy server.
- Health checks prevent traffic from reaching failed servers.
- Stateless servers are easier to scale than stateful servers.
- Layer 4 balances traffic using network information.
- Layer 7 can make application-aware routing decisions.
- Load balancers themselves must be redundant to avoid becoming a single point of failure.
Further Reading
These are the sources this lesson was checked against:
- Sam Rose: Load Balancing: an interactive essay that compares round robin, weighted and least-connections style strategies with animated traffic.
- System Design Primer: Load Balancer: layer 4 vs layer 7, health checks, and horizontal scaling.
- ByteByteGo: A Framework for System Design Interviews: where load balancers fit in a first high-level design.
Next: Caching, where QuickBite stores frequently accessed menus in memory so that most requests can be served without touching the database.