Dynamic load balancing makes real-time decisions to distribute incoming traffic or workloads across multiple servers based on current system conditions. It continuously adapts to changes such as server load, network traffic, and resource availability.
- Adjusts request distribution dynamically to prevent server overload.
- Improves performance and reliability by responding to real-time system changes.
Note: The choice between dynamic and static load balancing depends on system characteristics and workload behavior. Dynamic load balancing suits high-traffic, changing environments, while static load balancing works well for predictable scenarios.
Types of Dynamic Load Balancing Algorithms are:
- Least Connection Method Load Balancing Algorithm
- Least Response Time Method Load Balancing Algorithm
- Resource-based Load Balancing Algorithm
1. Least Connection Method Load Balancing Algorithm
The Least Connections algorithm is a dynamic load balancing technique that routes new requests to the server with the fewest active connections. It focuses on balancing workload by considering the current load on each server.
- Requires additional computation to track and identify the server with the least connections.
- More resource-intensive than round-robin due to real-time load evaluation.
- Provides better load distribution by basing decisions on active server connections.
For Example: Lets say you're at a playground, and some kids are playing on different swings. You want to join the swing with the fewest kids so that it's not too crowded. Least Connection is like choosing the swing with the least number of kids already on it.

Implementing the Least Connection Method Load Balancing Algorithms
A load balancing algorithm distributes incoming requests across multiple servers by routing new requests to the server with the fewest active connections. This helps balance workload and prevents overload on individual servers.
#include <iostream>
#include <map>
#include <string>
#include <limits>
class LeastConnectionLoadBalancer {
private:
std::map<std::string, int> serverConnections;
public:
LeastConnectionLoadBalancer() {}
void addServer(const std::string& serverName) {
serverConnections[serverName] = 0;
}
std::string getServerWithLeastConnections() {
int minConnections = std::numeric_limits<int>::max();
std::string selectedServer;
for (const auto& entry : serverConnections) {
if (entry.second < minConnections) {
minConnections = entry.second;
selectedServer = entry.first;
}
}
if (!selectedServer.empty()) {
serverConnections[selectedServer] = minConnections + 1;
}
return selectedServer;
}
};
int main() {
LeastConnectionLoadBalancer loadBalancer;
loadBalancer.addServer("Server1");
loadBalancer.addServer("Server2");
loadBalancer.addServer("Server3");
for (int i = 0; i < 10; ++i) {
std::string selectedServer = loadBalancer.getServerWithLeastConnections();
std::cout << "Request " << (i + 1) << ": Routed to " << selectedServer << std::endl;
}
return 0;
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class LeastConnectionLoadBalancer {
private Map<String, Integer> serverConnections;
public LeastConnectionLoadBalancer() {
this.serverConnections = new HashMap<>();
}
public void addServer(String serverName) {
// Add a server to the load balancer with 0 initial connections
serverConnections.put(serverName, 0);
}
public String getServerWithLeastConnections() {
// Find the server with the least active connections
int minConnections = Integer.MAX_VALUE;
String selectedServer = null;
for (Map.Entry<String, Integer> entry : serverConnections.entrySet()) {
if (entry.getValue() < minConnections) {
minConnections = entry.getValue();
selectedServer = entry.getKey();
}
}
// Increment the connection count for the selected server
if (selectedServer != null) {
serverConnections.put(selectedServer, minConnections + 1);
}
return selectedServer;
}
}
public class LeastConnectionLoadBalancerExample {
public static void main(String[] args) {
// Create a Least Connection load balancer
LeastConnectionLoadBalancer loadBalancer = new LeastConnectionLoadBalancer();
// Add servers to the load balancer
loadBalancer.addServer("Server1");
loadBalancer.addServer("Server2");
loadBalancer.addServer("Server3");
// Simulate requests and print the server to which each request is routed
for (int i = 0; i < 10; i++) {
String selectedServer = loadBalancer.getServerWithLeastConnections();
System.out.println("Request " + (i + 1) + ": Routed to " + selectedServer);
}
}
}
class LeastConnectionLoadBalancer:
def __init__(self):
self.server_connections = {}
def add_server(self, server_name):
# Add a server to the load balancer with 0 initial connections
self.server_connections[server_name] = 0
def get_server_with_least_connections(self):
# Find the server with the least active connections
min_connections = float('inf')
selected_server = None
for server, connections in self.server_connections.items():
if connections < min_connections:
min_connections = connections
selected_server = server
# Increment the connection count for the selected server
if selected_server is not None:
self.server_connections[selected_server] = min_connections + 1
return selected_server
if __name__ == '__main__':
# Create a Least Connection load balancer
load_balancer = LeastConnectionLoadBalancer()
# Add servers to the load balancer
load_balancer.add_server('Server1')
load_balancer.add_server('Server2')
load_balancer.add_server('Server3')
# Simulate requests and print the server to which each request is routed
for i in range(10):
selected_server = load_balancer.get_server_with_least_connections()
print(f'Request {i + 1}: Routed to {selected_server}')
class LeastConnectionLoadBalancer {
constructor() {
this.serverConnections = {};
}
addServer(serverName) {
// Add a server to the load balancer with 0 initial connections
this.serverConnections[serverName] = 0;
}
getServerWithLeastConnections() {
// Find the server with the least active connections
let minConnections = Infinity;
let selectedServer = null;
for (let server in this.serverConnections) {
if (this.serverConnections[server] < minConnections) {
minConnections = this.serverConnections[server];
selectedServer = server;
}
}
// Increment the connection count for the selected server
if (selectedServer !== null) {
this.serverConnections[selectedServer] = minConnections + 1;
}
return selectedServer;
}
}
if (require.main === module) {
// Create a Least Connection load balancer
const loadBalancer = new LeastConnectionLoadBalancer();
// Add servers to the load balancer
loadBalancer.addServer('Server1');
loadBalancer.addServer('Server2');
loadBalancer.addServer('Server3');
// Simulate requests and print the server to which each request is routed
for (let i = 0; i < 10; i++) {
const selectedServer = loadBalancer.getServerWithLeastConnections();
console.log(`Request ${i + 1}: Routed to ${selectedServer}`);
}
}
Output
Request 1: Routed to Server1 Request 2: Routed to Server2 Request 3: Routed to Server3 Request 4: Routed to Server1 Request 5: Routed to Server2 Request 6: Routed to Server3 Request 7: Routed to Serve...
- Defines a LeastConnectionLoadBalancer class that tracks active connections for each server
- Provides methods to add servers and select the server with the fewest active connections
- Demonstrates usage by adding servers and simulating requests to route traffic dynamically
Use Cases for Least Connection Algorithm
The Least Connection Algorithm is best suited for environments where request durations and connection lifetimes vary significantly.
- Ideal for applications with long-running requests, such as video streaming or large file uploads.
- Ensures new requests are routed to servers with fewer active connections.
- Effectively handles fluctuating traffic by balancing load based on real-time server connections.
Benefits and Drawbacks of Least Connection Algorithm
The Least Connection Algorithm dynamically distributes traffic based on current server connections, offering efficient load balancing with certain limitations.
Benefits: The Least Connection Algorithm helps distribute traffic efficiently by considering current server load.
- Balanced Load: Routes traffic to servers with the fewest active connections, reducing overload.
- Dynamic: Adapts quickly to changing server workloads.
Drawbacks: Despite its efficiency, this algorithm has some limitations.
- Ignored Capacities: Does not account for server capacity; fewer connections may not mean more available resources.
- Sticky Sessions: Not ideal for applications that require session persistence.
2. Least Response Time Method Load Balancing Algorithm
The Least Response method is a dynamic load balancing approach that aims to minimize response times by directing new requests to the server with the quickest response time.
- It considers the historical performance of servers to make decisions about where to route incoming requests, optimizing for faster processing.
- The dynamic aspect comes from the continuous monitoring of server response times and the adaptive nature of the algorithm to route incoming requests to the server with the historically lowest response time.
For Example: Picture yourself at a snack bar where you can order food from different servers. You notice that some servers are faster than others. You choose the server that seems to serve food the quickest each time you go. Least Response Time is like picking the server with the shortest line.

Implementing the Least Response Time Load Balancing Algorithms
A load balancing algorithm distributes incoming requests across multiple servers by directing new requests to the server with the least accumulated response time. This approach balances workload and optimizes overall system performance.
#include <map>
#include <string>
#include <limits>
#include <iostream>
class LeastResponseLoadBalancer {
private:
std::map<std::string, long long> serverResponseTimes;
public:
LeastResponseLoadBalancer() {}
void addServer(const std::string& serverName) {
serverResponseTimes[serverName] = 0;
}
std::string getServerWithLeastResponseTime() {
long long minResponseTime = std::numeric_limits<long long>::max();
std::string selectedServer;
for (const auto& entry : serverResponseTimes) {
if (entry.second < minResponseTime) {
minResponseTime = entry.second;
selectedServer = entry.first;
}
}
if (!selectedServer.empty()) {
serverResponseTimes[selectedServer] = minResponseTime + 1;
}
return selectedServer;
}
};
int main() {
LeastResponseLoadBalancer loadBalancer;
loadBalancer.addServer("Server1");
loadBalancer.addServer("Server2");
loadBalancer.addServer("Server3");
for (int i = 0; i < 10; ++i) {
std::string selectedServer = loadBalancer.getServerWithLeastResponseTime();
std::cout << "Request " << (i + 1) << ": Routed to " << selectedServer << std::endl;
}
return 0;
}
import java.util.HashMap;
import java.util.Map;
class LeastResponseLoadBalancer {
private Map<String, Long> serverResponseTimes;
public LeastResponseLoadBalancer() {
this.serverResponseTimes = new HashMap<>();
}
public void addServer(String serverName) {
serverResponseTimes.put(serverName, 0L);
}
public String getServerWithLeastResponseTime() {
long minResponseTime = Long.MAX_VALUE;
String selectedServer = null;
for (Map.Entry<String, Long> entry : serverResponseTimes.entrySet()) {
if (entry.getValue() < minResponseTime) {
minResponseTime = entry.getValue();
selectedServer = entry.getKey();
}
}
if (selectedServer != null) {
serverResponseTimes.put(selectedServer, minResponseTime + 1);
}
return selectedServer;
}
}
public class LeastResponseLoadBalancerExample {
public static void main(String[] args) {
LeastResponseLoadBalancer loadBalancer = new LeastResponseLoadBalancer();
loadBalancer.addServer("Server1");
loadBalancer.addServer("Server2");
loadBalancer.addServer("Server3");
for (int i = 0; i < 10; i++) {
String selectedServer = loadBalancer.getServerWithLeastResponseTime();
System.out.println("Request " + (i + 1) + ": Routed to " + selectedServer);
}
}
}
class LeastResponseLoadBalancer:
def __init__(self):
self.server_response_times = {}
def add_server(self, server_name):
self.server_response_times[server_name] = 0
def get_server_with_least_response_time(self):
min_response_time = float('inf')
selected_server = None
for server, response_time in self.server_response_times.items():
if response_time < min_response_time:
min_response_time = response_time
selected_server = server
if selected_server is not None:
self.server_response_times[selected_server] = min_response_time + 1
return selected_server
if __name__ == "__main__":
load_balancer = LeastResponseLoadBalancer()
load_balancer.add_server("Server1")
load_balancer.add_server("Server2")
load_balancer.add_server("Server3")
for i in range(10):
selected_server = load_balancer.get_server_with_least_response_time()
print(f'Request {i + 1}: Routed to {selected_server}')
class LeastResponseLoadBalancer {
constructor() {
this.serverResponseTimes = {};
}
addServer(serverName) {
this.serverResponseTimes[serverName] = 0;
}
getServerWithLeastResponseTime() {
let minResponseTime = Infinity;
let selectedServer = null;
for (let server in this.serverResponseTimes) {
if (this.serverResponseTimes[server] < minResponseTime) {
minResponseTime = this.serverResponseTimes[server];
selectedServer = server;
}
}
if (selectedServer !== null) {
this.serverResponseTimes[selectedServer] = minResponseTime + 1;
}
return selectedServer;
}
}
if (require.main === module) {
let loadBalancer = new LeastResponseLoadBalancer();
loadBalancer.addServer("Server1");
loadBalancer.addServer("Server2");
loadBalancer.addServer("Server3");
for (let i = 0; i < 10; i++) {
let selectedServer = loadBalancer.getServerWithLeastResponseTime();
console.log(`Request ${i + 1}: Routed to ${selectedServer}`);
}
}
Output
Request 1: Routed to Server1 Request 2: Routed to Server2 Request 3: Routed to Server3 Request 4: Routed to Server1 Request 5: Routed to Server2 Request 6: Routed to Server3 Request 7: Routed to Serve...
- Defines a LeastResponseLoadBalancer class that tracks accumulated response times for each server.
- Provides methods to add servers and select the server with the least response time.
- Demonstrates usage by adding servers and simulating requests routed based on response time.
Use Cases for Least Response Time Algorithm
The Least Response Time Algorithm is well suited for performance-critical systems where fast responses are essential.
- Ideal for applications with heavy and fluctuating traffic where response time is crucial.
- Enhances user experience in platforms like e-commerce or streaming services.
- Effectively handles servers with varying loads by routing requests to the fastest-responding server.
Benefits and Drawbacks of Least Response Time Algorithm
The Least Response Time Algorithm improves request routing by considering server responsiveness, but it also introduces added complexity.
Benefits: The Least Response Time Algorithm enhances performance by making routing decisions based on server responsiveness.
- Optimized Performance: Routes traffic to servers with the lowest response times, improving overall system performance
- Adaptable: Adjusts dynamically to changes in server responsiveness
Drawbacks: Despite its advantages, the algorithm introduces additional complexity.
- Historical Bias: Depends on past response times, which may not always represent current server capacity
- Complex Implementation: Requires continuous tracking and management of response time data
3. Resource-based Load Balancing Algorithm
The Resource-Based Load Balancing algorithm distributes incoming requests based on the current resource availability of each server, such as CPU usage, memory, or network bandwidth. Rather than just routing traffic equally or based on past performance, this algorithm evaluates the current "resource health" of each server to decide where new requests should go.

For Example: Imagine it like assigning tasks in an office based on each employee’s workload at the moment—some are busy, while others are free. Resource-Based Load Balancing directs requests to the server with the most available resources.
Implementing the Resource-based Load Balancing Algorithms
Resource-based load balancing routes incoming requests by evaluating each server’s real-time resource usage to select the most suitable server.
- Tracks current server resources such as CPU load.
- Selects the server with the most available capacity for each request.
- Uses real-time data to optimize performance and prevent overload.
#include <iostream>
#include <map>
#include <limits>
#include <string>
class Server {
private:
std::string name;
double cpuLoad;
public:
// Default constructor
Server() : name(""), cpuLoad(0.0) {}
// Parameterized constructor
Server(const std::string& name) : name(name), cpuLoad(0.0) {}
void updateCpuLoad(double load) {
cpuLoad = load;
}
double getCpuLoad() const {
return cpuLoad;
}
std::string getName() const {
return name;
}
};
class ResourceBasedLoadBalancer {
private:
std::map<std::string, Server> servers;
public:
void addServer(const Server& server) {
servers[server.getName()] = server;
}
void updateServerLoad(const std::string& name, double load) {
if (servers.find(name) != servers.end()) {
servers[name].updateCpuLoad(load);
}
}
// Returns pointer to server with lowest CPU load
Server* getServerWithMostResources() {
Server* bestServer = nullptr;
double lowestLoad = std::numeric_limits<double>::max();
for (auto& [_, server] : servers) {
if (server.getCpuLoad() < lowestLoad) {
lowestLoad = server.getCpuLoad();
bestServer = &server;
}
}
return bestServer;
}
void handleRequest() {
Server* bestServer = getServerWithMostResources();
if (bestServer) {
std::cout << "Routing request to server: "
<< bestServer->getName()
<< " with current CPU load: "
<< bestServer->getCpuLoad() << "%\n";
} else {
std::cout << "No servers available.\n";
}
}
};
int main() {
ResourceBasedLoadBalancer loadBalancer;
// Add servers
loadBalancer.addServer(Server("Server1"));
loadBalancer.addServer(Server("Server2"));
loadBalancer.addServer(Server("Server3"));
// Update CPU loads
loadBalancer.updateServerLoad("Server1", 30.0);
loadBalancer.updateServerLoad("Server2", 50.0);
loadBalancer.updateServerLoad("Server3", 20.0);
// Handle request
loadBalancer.handleRequest(); // Correctly routes to Server3
return 0;
}
import java.util.HashMap;
import java.util.Map;
class Server {
String name;
double cpuLoad; // Represents the current CPU load percentage of the server
public Server(String name) {
this.name = name;
this.cpuLoad = 0.0;
}
// Simulate updating the CPU load for the server
public void updateCpuLoad(double load) {
this.cpuLoad = load;
}
public double getCpuLoad() {
return this.cpuLoad;
}
public String getName() {
return this.name;
}
}
class ResourceBasedLoadBalancer {
private Map<String, Server> servers;
public ResourceBasedLoadBalancer() {
this.servers = new HashMap<>();
}
// Adds a server to the load balancer
public void addServer(Server server) {
servers.put(server.getName(), server);
}
// Finds the server with the lowest CPU load and assigns the request to it
public Server getServerWithMostResources() {
Server bestServer = null;
double lowestLoad = Double.MAX_VALUE;
for (Server server : servers.values()) {
if (server.getCpuLoad() < lowestLoad) {
lowestLoad = server.getCpuLoad();
bestServer = server;
}
}
return bestServer;
}
// Simulate handling a request
public void handleRequest() {
Server bestServer = getServerWithMostResources();
if (bestServer != null) {
System.out.println("Routing request to server: " + bestServer.getName() + " with current CPU load: " + bestServer.getCpuLoad() + "%");
// Here, you might update the server's load after handling a request
} else {
System.out.println("No servers available.");
}
}
}
public class ResourceBasedLoadBalancerExample {
public static void main(String[] args) {
ResourceBasedLoadBalancer loadBalancer = new ResourceBasedLoadBalancer();
// Create servers and add them to the load balancer
Server server1 = new Server("Server1");
Server server2 = new Server("Server2");
Server server3 = new Server("Server3");
loadBalancer.addServer(server1);
loadBalancer.addServer(server2);
loadBalancer.addServer(server3);
// Simulate updating CPU load for each server
server1.updateCpuLoad(30.0);
server2.updateCpuLoad(50.0);
server3.updateCpuLoad(20.0);
// Route requests based on current CPU load
loadBalancer.handleRequest(); // This should route to Server3, as it has the lowest CPU load
}
}
class Server:
def __init__(self, name):
self.name = name
self.cpuLoad = 0.0 # Represents the current CPU load percentage of the server
# Simulate updating the CPU load for the server
def updateCpuLoad(self, load):
self.cpuLoad = load
def getCpuLoad(self):
return self.cpuLoad
def getName(self):
return self.name
class ResourceBasedLoadBalancer:
def __init__(self):
self.servers = {}
# Adds a server to the load balancer
def addServer(self, server):
self.servers[server.getName()] = server
# Finds the server with the lowest CPU load and assigns the request to it
def getServerWithMostResources(self):
bestServer = None
lowestLoad = float('inf')
for server in self.servers.values():
if server.getCpuLoad() < lowestLoad:
lowestLoad = server.getCpuLoad()
bestServer = server
return bestServer
# Simulate handling a request
def handleRequest(self):
bestServer = self.getServerWithMostResources()
if bestServer is not None:
print(f'Routing request to server: {bestServer.getName()} with current CPU load: {bestServer.getCpuLoad()}%')
# Here, you might update the server's load after handling a request
else:
print('No servers available.')
if __name__ == '__main__':
loadBalancer = ResourceBasedLoadBalancer()
# Create servers and add them to the load balancer
server1 = Server('Server1')
server2 = Server('Server2')
server3 = Server('Server3')
loadBalancer.addServer(server1)
loadBalancer.addServer(server2)
loadBalancer.addServer(server3)
# Simulate updating CPU load for each server
server1.updateCpuLoad(30.0)
server2.updateCpuLoad(50.0)
server3.updateCpuLoad(20.0)
# Route requests based on current CPU load
loadBalancer.handleRequest() # This should route to Server3, as it has the lowest CPU load
class Server {
constructor(name) {
this.name = name;
this.cpuLoad = 0.0; // Represents the current CPU load percentage of the server
}
// Simulate updating the CPU load for the server
updateCpuLoad(load) {
this.cpuLoad = load;
}
getCpuLoad() {
return this.cpuLoad;
}
getName() {
return this.name;
}
}
class ResourceBasedLoadBalancer {
constructor() {
this.servers = {};
}
// Adds a server to the load balancer
addServer(server) {
this.servers[server.getName()] = server;
}
// Finds the server with the lowest CPU load and assigns the request to it
getServerWithMostResources() {
let bestServer = null;
let lowestLoad = Infinity;
for (let server of Object.values(this.servers)) {
if (server.getCpuLoad() < lowestLoad) {
lowestLoad = server.getCpuLoad();
bestServer = server;
}
}
return bestServer;
}
// Simulate handling a request
handleRequest() {
let bestServer = this.getServerWithMostResources();
if (bestServer !== null) {
console.log(`Routing request to server: ${bestServer.getName()} with current CPU load: ${bestServer.getCpuLoad()}%`);
// Here, you might update the server's load after handling a request
} else {
console.log('No servers available.');
}
}
}
if (require.main === module) {
let loadBalancer = new ResourceBasedLoadBalancer();
// Create servers and add them to the load balancer
let server1 = new Server('Server1');
let server2 = new Server('Server2');
let server3 = new Server('Server3');
loadBalancer.addServer(server1);
loadBalancer.addServer(server2);
loadBalancer.addServer(server3);
// Simulate updating CPU load for each server
server1.updateCpuLoad(30.0);
server2.updateCpuLoad(50.0);
server3.updateCpuLoad(20.0);
// Route requests based on current CPU load
loadBalancer.handleRequest(); // This should route to Server3, as it has the lowest CPU load
}
Output
Routing request to server: Server3 with current CPU load: 20.0%
- Defines a Server class that represents a server and simulates real-time CPU load updates.
- Implements a ResourceBasedLoadBalancer to manage servers and route requests based on available resources.
- Demonstrates usage by adding servers, updating CPU loads, and routing requests accordingly.
Use Cases for Resource-Based Load Balancing Algorithm
Resource-based load balancing is ideal for environments where server capacity varies and efficient resource utilization is critical.
- Useful for applications performing CPU-intensive or memory-heavy tasks.
- Adapts well to servers with different resource capacities by using real-time data.
- Improves availability by routing requests to the least overloaded servers.
Benefits and Drawbacks of Resource-Based Load Balancing Algorithm
This algorithm makes load distribution decisions based on real-time server resource usage, offering efficiency with added complexity.
Benefits: Resource-based load balancing improves efficiency by making decisions based on actual server resource usage.
- Resource Optimization: Distributes workload using real-time CPU, memory, or disk usage data.
- Adaptability: Dynamically adjusts to changing server resource conditions.
Drawbacks: Despite its effectiveness, this approach introduces additional complexity.
- Complex Implementation: Requires continuous monitoring of server resources.
- Higher Overhead: Real-time tracking can consume extra system resources.