Load Balancer
Load balancing ensures calls are distributed evenly across your destinations. The load balancer determines which destination to try first based on current load, prioritizing less busy destinations. Destinations are called sequentially (one at a time) in order of least to most loaded, ensuring even distribution when using the same balancer across multiple groups.
Why Use Load Balancing?
Without load balancing, if you ring ["user/1001", "user/1002", "user/1003"] in multiple groups, user/1001 will always be tried first in each group and may become overloaded while others remain idle.
With load balancing, the system tracks how many active calls each destination is handling and tries destinations in order from least to most loaded. This ensures that less busy destinations are contacted first, preventing specific destinations from being overloaded when using the same balancer instance across multiple groups.
Strategies
Choose the load balancer backend based on your deployment architecture:
Single Instance
If you’re running a single instance of your application, use InMemoryLoadBalancer:
from genesis import Inbound, RingGroup, RingMode, InMemoryLoadBalancer
async with Inbound("127.0.0.1", 8021, "ClueCon") as client:
# Create load balancer once and reuse it
balancer = InMemoryLoadBalancer()
# Each call will be routed to the least busy agent
answered = await RingGroup.ring(
client,
["user/1001", "user/1002", "user/1003"],
RingMode.BALANCING,
balancer=balancer
)The load balancer automatically tracks active calls and distributes them evenly. Create it once and reuse it across multiple ring operations. If the same balancer instance is used with different groups, destinations that appear in multiple groups will have their load tracked correctly.
Multiple Instances
If you’re running multiple instances of your application, use RedisLoadBalancer so all instances can coordinate:
from genesis import Inbound, RingGroup, RingMode, RedisLoadBalancer
# Create load balancer with Redis URL
# The redis package is automatically installed if needed
balancer = RedisLoadBalancer("redis://localhost:6379")
async with Inbound("127.0.0.1", 8021, "ClueCon") as client:
answered = await RingGroup.ring(
client,
["user/1001", "user/1002", "user/1003"],
RingMode.BALANCING,
balancer=balancer
)All application instances share the same Redis connection, so they coordinate load distribution across the entire cluster. The redis package is automatically installed when needed.
Custom Redis Key Prefix
If you need to avoid key collisions in Redis, customize the prefix:
balancer = RedisLoadBalancer("redis://localhost:6379", key_prefix="myapp:lb:")Best Practices
Create the load balancer instance once and reuse it across all ring operations
Use
InMemoryLoadBalancerfor single-instance deployments,RedisLoadBalancerwhen running multiple instancesIf Redis becomes unavailable,
RedisLoadBalancerwill raise exceptions. Ensure your application handles these errors appropriately
Related
- Ring Group - Learn about ring groups
- Observability - Monitor load balancer metrics and distribution
- Group Call Example - See a complete example