WebSocket Load Balancer — Basic Load Balancing (Part 1)
Learn this problemProblem statement
Stripe's notebook platform is based on Jupyter, which does not perform well with a large number of users. To provide a good developer experience, Stripe runs multiple Jupyter servers and directs developers to different servers according to current load.
Each incoming request represents a WebSocket connection. Once it reaches a target Jupyter server, the connection remains alive indefinitely and continuously contributes load. This exercise does not route requests over the network; routeRequests only determines the target for each incoming request.
Implement routeRequests, the Java-style execution adapter for the source function route_requests. The targets are numbered from 1 through numTargets.
Part 1: Basic load balancing (test cases 1–4)
For this exercise, assume every target starts with zero active connections. Process the requests in the order received. For every request:
- Choose a target with the smallest current number of active connections.
- If several targets have the same load, choose the one with the smaller target index.
- Assign the connection to that target. Because connections do not end in Part 1, its active-connection count increases by one and never decreases.
Routing in Part 1 is independent of the user's other requests. The objectId field also does not affect this basic load-balancing decision.
Request records
For this exercise, assume every request is a valid Part 1 record with the following comma-separated form:
CONNECT,connectionId,userId,objectIdFor this exercise, assume every field is non-empty and does not contain a comma. The full source also lists an action,targetIndex schema for later parts, but those actions are not part of this Part 1 practice because their rules are not visible.
The parameter maxConnectionsPerTarget is retained because it appears in the source interface. The source explicitly marks it as used in Part 4, so it does not limit assignments in Part 1.
Return one log string for every CONNECT request, in input order, using the format:
connectionId,userId,targetIndexThe returned targetIndex is one-based.
Function
routeRequests(numTargets: int, maxConnectionsPerTarget: int, requests: String[]) → String[]Examples
Example 1
numTargets = 3maxConnectionsPerTarget = 10requests = ["CONNECT,c1,u1,o1","CONNECT,c2,u2,o2","CONNECT,c3,u3,o3","CONNECT,c4,u4,o4","CONNECT,c5,u5,o5"]return = ["c1,u1,1","c2,u2,2","c3,u3,3","c4,u4,1","c5,u5,2"]The first three connections take targets 1, 2, and 3 by the smaller-index tie-break. After all targets have load 1, the next tie again starts at target 1, followed by target 2.
Example 2
numTargets = 2maxConnectionsPerTarget = 1requests = ["CONNECT,a,sameUser,sameObject","CONNECT,b,sameUser,sameObject","CONNECT,c,sameUser,otherObject","CONNECT,d,otherUser,sameObject"]return = ["a,sameUser,1","b,sameUser,2","c,sameUser,1","d,otherUser,2"]Part 1 uses only current target load, so repeated users and objects do not change the assignments. The value maxConnectionsPerTarget = 1 is not enforced in Part 1 because the source reserves that parameter for Part 4.
Constraints
- For this exercise, assume
1 <= numTargets <= 10^5. - For this exercise, assume every target starts with zero active connections.
- For this exercise, assume
1 <= maxConnectionsPerTarget <= 10^9; this value is retained but not used in Part 1. - For this exercise, assume
1 <= requests.length <= 2 * 10^5. - Every request is a valid
CONNECT,connectionId,userId,objectIdrecord whose fields are non-empty and contain no commas. - Target indices in the returned logs are one-based.
More Stripe problems
- Group Linked Merchant RecordsPHONE SCREEN · Seen Jul 2026
- Invoice / Payment ReconciliationPHONE SCREEN · Seen Jul 2026
- Incident MonitorOA · Seen Jul 2026
- Merchant Fraud Risk ScoringOA · Seen Jul 2026
- Rule-Driven Transaction Fraud DetectionOA · PHONE SCREEN · Seen Jul 2026
- Deployment Window SchedulerOA · Seen Jul 2026
- Directly Linked UsersOA · Seen Jun 2026
- Fraud Ring SizeOA · Seen Jun 2026