How to design a load balancer from scratch?

Designing a load balancer from scratch involves understanding the core concepts of load balancing and implementing the necessary components to distribute traffic efficiently across multiple servers. Here’s a step-by-step guide to help you design a basic load balancer:

Key Concepts

  1. Load Balancing Algorithms: Determines how incoming requests are distributed.

    • Round Robin: Distributes requests sequentially.
    • Least Connections: Sends requests to the server with the fewest active connections.
    • IP Hash: Uses the client’s IP address to determine which server receives the request.
    • Weighted Round Robin: Each server is assigned a weight, and requests are distributed based on these weights.
  2. Health Checks: Regularly check the status of each server to ensure it's capable of handling requests.

  3. Session Persistence (Sticky Sessions): Ensures requests from the same client are always sent to the same server.

  4. Failover: Ensures requests are rerouted to healthy servers if a server fails.

  5. Scalability: Ability to handle increasing traffic by adding more servers.

Step-by-Step Implementation

1. Define the Server Pool

First, define a pool of servers that the load balancer will distribute traffic to.

class Server: def __init__(self, ip, weight=1): self.ip = ip self.weight = weight self.active_connections = 0 servers = [ Server("192.168.1.1", weight=1), Server("192.168.1.2", weight=1), Server("192.168.1.3", weight=2) ]

2. Implement Load Balancing Algorithms

Implement a simple round-robin algorithm to distribute requests.

class LoadBalancer: def __init__(self, servers): self.servers = servers self.current_index = 0 def get_next_server(self): server = self.servers[self.current_index] self.current_index = (self.current_index + 1) % len(self.servers) return server load_balancer = LoadBalancer(servers) # Example request handling for _ in range(6): server = load_balancer.get_next_server() print(f"Forwarding request to {server.ip}")

Implement the least connections algorithm.

class LeastConnectionsLoadBalancer: def __init__(self, servers): self.servers = servers def get_next_server(self): # Get the server with the least active connections server = min(self.servers, key=lambda s: s.active_connections) server.active_connections += 1 return server load_balancer = LeastConnectionsLoadBalancer(servers) # Example request handling for _ in range(6): server = load_balancer.get_next_server() print(f"Forwarding request to {server.ip}") server.active_connections -= 1 # Simulate the request being processed

3. Implement Health Checks

Regularly check if servers are healthy and can handle requests.

import requests def is_server_healthy(server): try: response = requests.get(f"http://{server.ip}/health") return response.status_code == 200 except requests.RequestException: return False class HealthCheckLoadBalancer: def __init__(self, servers): self.servers = servers def get_next_server(self): healthy_servers = [s for s in self.servers if is_server_healthy(s)] if not healthy_servers: raise Exception("No healthy servers available") return min(healthy_servers, key=lambda s: s.active_connections) load_balancer = HealthCheckLoadBalancer(servers) # Example request handling for _ in range(6): try: server = load_balancer.get_next_server() print(f"Forwarding request to {server.ip}") except Exception as e: print(e)

4. Implement Session Persistence (Sticky Sessions)

Ensure requests from the same client are always sent to the same server.

class StickySessionLoadBalancer: def __init__(self, servers): self.servers = servers self.session_map = {} def get_next_server(self, client_id): if client_id in self.session_map: return self.session_map[client_id] server = min(self.servers, key=lambda s: s.active_connections) self.session_map[client_id] = server return server load_balancer = StickySessionLoadBalancer(servers) # Example request handling client_id = "client1" for _ in range(6): server = load_balancer.get_next_server(client_id) print(f"Forwarding request from {client_id} to {server.ip}")

5. Implement Failover

Ensure requests are rerouted to healthy servers if a server fails.

class FailoverLoadBalancer: def __init__(self, servers): self.servers = servers def get_next_server(self): for server in self.servers: if is_server_healthy(server): return server raise Exception("No healthy servers available") load_balancer = FailoverLoadBalancer(servers) # Example request handling for _ in range(6): try: server = load_balancer.get_next_server() print(f"Forwarding request to {server.ip}") except Exception as e: print(e)

Conclusion

Designing a load balancer from scratch involves implementing key functionalities like load balancing algorithms, health checks, session persistence, and failover mechanisms. The provided examples illustrate basic implementations of these concepts. In a production environment, you would need to add more sophisticated features, optimize performance, and ensure security. This foundational understanding will help you build and scale load balancers effectively.

Learn more about Load Balancing.

TAGS
System Design Interview
Load Balancer
CONTRIBUTOR
Arslan Ahmad
Arslan Ahmad
ex-FAANG engineering manager and author or Grokking series.

GET YOUR FREE

Coding Questions Catalog

Design Gurus Newsletter - Latest from our Blog
Boost your coding skills with our essential coding questions catalog.
Take a step towards a better tech career now!
Explore Answers
What questions are asked in a Microsoft interview?
DoorDash System Design Interview Questions (and How to Answer Them)
DoorDash design rounds center on delivery: order flow, driver matching, live location tracking, maps and routing, pricing and payments.
What questions should I ask Airbnb?
How do you handle communication between microservices?
What is a Key Management System (KMS)?
A Key Management System (KMS) securely generates, stores, and rotates cryptographic keys for encryption. Learn use cases, trade-offs, and interview tips.
What is the technical interview methodology?
Related Courses
New
Grokking the AI System Design Interview course cover
Grokking the AI System Design Interview
Learn to design AI systems the way interviewers expect: classic ML products, LLM and RAG architectures, and agentic systems, all through the lens of the system design interview.
4.6
(3,192 learners)
Discounted price for Your Region

$99

Grokking the Coding Interview: Patterns for Coding Questions course cover
Grokking the Coding Interview: Patterns for Coding Questions
The 24 essential patterns behind every coding interview question. Available in Java, Python, JavaScript, C++, C#, and Go. The most comprehensive coding interview course with 543 lessons. A smarter alternative to grinding LeetCode.
4.6
Discounted price for Your Region

$197

Grokking Modern AI Fundamentals course cover
Grokking Modern AI Fundamentals
Master the fundamentals of AI today to lead the tech revolution of tomorrow.
4.1
Discounted price for Your Region

$72

Design Gurus logo
One-Stop Portal For Tech Interviews.
About Us
Our Team
Careers
Partners
Contact Us
Become Affiliate
Copyright © 2026 Design Gurus, LLC. All rights reserved.