Load Balancing in Robot Fleet Systems
/ 4 min read
Table of Contents
Load balancing in robotics is different from web applications. You have mixed communication patterns - real-time sensor data via pub/sub and computational tasks via request/response. Each pattern needs different balancing strategies that depends on latency, reliability, and processing requirments.
Request/Response Load Balancing
Path planning, safety validation, and navigation queries use request/response pattern. These are synchronous calls where robot waits for result before continuing. Round-robin works for stateless services like map queries, but complex path planning get benefits from least-connections routing.
Example implementation:
FleetManager maintains list of planning services:- planner_1: current_load=2, max_capacity=5- planner_2: current_load=4, max_capacity=5- planner_3: current_load=1, max_capacity=3
For new path planning request, route to planner_3 (lowest current_load ratio)Sticky routing is important for multi-step operations. If robot start path planning session with planner A, subsequent refinement requests should go to same instance that has context.
Example:
robot_001 → hash(robot_001) % 3 = planner_2robot_002 → hash(robot_002) % 3 = planner_1robot_003 → hash(robot_003) % 3 = planner_2
All requests from robot_001 always go to planner_2Publisher/Subscriber Load Balancing
Sensor data, robot status updates, and telemetry use pub/sub pattern. Challenge here is subscribers with different processing speeds - fast services handle messages immediately, slow ones create backlog and memory pressure issues.
Example with message queues:
Message routing by robot ID:- queue_A: handles robot_001, robot_004, robot_007- queue_B: handles robot_002, robot_005, robot_008- queue_C: handles robot_003, robot_006, robot_009
Each queue has dedicated worker thread/processIf worker_B is slow, only affects robots 002, 005, 008We partition topics by robot_id. Each partition get dedicated subscriber instance, so slow processing on robot_1 doesn’t affect robot_2 messages.
Priority-based processing:
Same messages sent to multiple queues:- safety_queue: processes emergency_stop in <10ms- dashboard_queue: updates UI every 100ms- logging_queue: writes to database every 5s
Each queue processes same messages at different speedsFast queues don't wait for slow onesData Storage Load Balancing
Robot fleets generate massive amounts of sensor data. Better to separate real-time data (current position, immediate sensor readings) from historical data (maps, trajectory logs, maintenance records).
Storage tier example:
Fast storage (in-memory):- robot_position: expires after 1 minute- sensor_readings: expires after 5 minutes- emergency_status: never expires
Slow storage (disk-based):- trajectory_logs: files organized by day- maintenance_records: archived after 2 years- map_updates: versioned with rollback capabilityReal-time data can go to fast storage with read replicas for dashboard queries. Historical data can go to cheaper bulk storage with different retention policy.
Query routing example:
Time-based routing:- Query last 1 hour → memory cache (3 servers)- Query last 1 day → fast disk storage- Query last 1 month → warm disk storage- Query > 1 month → cold archive storage
Robot-based sharding:- robots 1-100 → database_server_1- robots 101-200 → database_server_2- robots 201-300 → database_server_3Time-series databases work well for sensor data and logs. We partition by robot_id and time ranges - recent data stay in fast storage, older data move to archive. Query routing depend on time range requested.
Communication Pattern Trade-offs
Request/Response balancing:
- Pro: Immediate feedback, easier error handling
- Con: Synchronous blocking, cascading failures
- Use for: Path planning, safety checks, configuration queries
Pub/Sub balancing:
- Pro: Decoupled processing, handles different speeds well
- Con: No direct feedback, harder to debug failures
- Use for: Sensor streams, status updates, telemetry
Mixed approach work best:
- Critical operations use request/response for reliability
- Background data use pub/sub for throughput
- Emergency messages bypass load balancing entirely
Real system example:
Fleet Controller Architecture:
1. Fleet Manager (Load Balancer): - Receive robot requests via HTTP/gRPC - Route to appropriate service based on request type - Maintain service registry and health checks
2. Service Registry: - planner_service: {instances: [host1:8080, host2:8080], load: [2,4]} - safety_service: {instances: [host1:8081, host2:8081], load: [1,1]} - map_service: {instances: [host1:8082], load: [3]}
3. Message Queues: - sensor_data: 9 queues, 3 worker processes - robot_status: 3 queues, 2 worker processes - emergency: broadcast to all workers immediately
4. Storage Layer: - Memory cache: current robot state, active tasks - Fast disk: sensor time-series, performance metrics - Archive disk: configuration, maps, maintenance logsChoosing the Right Strategy
Use round-robin when:
- Robots have similar capabilities
- Tasks are homogeneous and quick
- Simple setup is priority
Use capability-based routing when:
- Robots have different hardware (sensors, actuators)
- Tasks require specific capabilities
- Efficiency matters more than simplicity
Use geographic partitioning when:
- Fleet spans multiple zones or buildings
- Network latency is significant
- Local processing is preferred
Use priority queuing when:
- Safety messages must be processed immediately
- Different message types have different urgency
- System can handle complex routing logic
The key insight is that robot systems is not just about throughput - latency and reliability often matter more. We prioritize consistent response times over maximum throughput, especially for safety-critical operation.