Session 8 · Running Locust in distributed mode#
The big idea#
One Locust process can only generate so much load before your own computer becomes the bottleneck. Python runs one CPU core per process. For bigger tests you start one master (the coordinator) and several workers (the load generators). The master splits the users between workers and adds up the results. The same locustfile runs everywhere.
Everyday example: a call centre. One supervisor (master) does not make all the calls. She hands out the call list to several agents (workers), then collects everybody’s results into one report. For ten times the calls, hire more agents.
One master, two workers on this computer#
The worker processes are started first (any number, anywhere that can reach the master); the master waits for them.
locust -f 05_http.py --worker # run twice, in two terminals
locust -f 05_http.py --master --expect-workers 2 --headless -u 6 -r 6 -t 8s --only-summary
Locust looks for the master on the same computer by default. From another computer, add --master-host=<master-ip>.
The master’s output:
root: Waiting for workers to be ready, 0 of 2 connected
locust.runners: Worker <id> (index 0) reported as ready. 1 workers connected.
locust.runners: Worker <id> (index 1) reported as ready. 2 workers connected.
locust.main: Run time limit set to 8 seconds
locust.main: Starting Locust 2.28.0
locust.runners: Sending spawn jobs of 6 users at 6.00 spawn rate to 2 ready workers
locust.runners: All users spawned: {"ShopUser": 6} (6 total users)
locust.main: --run-time limit reached, shutting down
locust.runners: Worker 'syedjaferk_e97dc1b000c24bd29330f82178abc7a3' (index 1) quit. 0 workers ready.
locust.runners: Worker 'syedjaferk_9f3e8d9e467343c58b8d1460b69b1dab' (index 0) quit. 0 workers ready.
locust.runners: The last worker quit, stopping test.
locust.main: Shutting down (exit code 0)
Type Name # reqs # fails | Avg Min Max Med | req/s failures/s
--------|----------------------------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
POST /login 6 0(0.00%) | 8 6 9 8 | 0.75 0.00
POST /orders 16 0(0.00%) | 2 1 3 3 | 2.01 0.00
GET /products 80 0(0.00%) | 2 1 3 3 | 10.06 0.00
GET /products/[id] 53 0(0.00%) | 2 1 9 3 | 6.66 0.00
GET /profile 38 0(0.00%) | 2 1 4 3 | 4.78 0.00
--------|----------------------------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
Aggregated 193 0(0.00%) | 2 1 9 3 | 24.27 0.00
Reading it from the top:
Waiting for workers: the master will not start until
--expect-workers 2workers have connected.Both workers say they are ready, then the master sends the spawn jobs of 6 users to the 2 ready workers, who share them.
All users spawned: ShopUser: 6 confirms the total.
When the time limit is reached the workers quit, and the master prints one combined table, as if a single process had made all the requests.
When do you need it?#
Situation |
Do |
|---|---|
Learning, small API, a few hundred users |
One process is fine |
Your CPU is at 100% while testing |
Add workers (one per CPU core is a good start) |
Need load from different regions |
Run workers on machines in those regions |
CI pipelines |
Headless master with workers started by the pipeline |
The master itself should not be the busiest machine: keep it free to coordinate and gather stats.
Common mistakes#
Starting the master before the workers without
--expect-workers. The test begins with no load generators.Workers with a different locustfile than the master. Every process must use the same file.
Firewalls blocking the master’s port (5557). Workers cannot join. Open the port or use the same network.
Expecting more load from more workers when the server is already the bottleneck. If the service is slow, adding workers just adds queueing.
Forgetting to count the generators. When the load machine’s CPU is above about 80%, results are unreliable.
Leaving workers running afterwards. Stop them when the master finishes.
Hands-on exercises#
Exercise 1. How would you start 4 workers on a 4-core machine with a script?
Solution
for i in 1 2 3 4; do locust -f 05_http.py --worker & done
locust -f 05_http.py --master --expect-workers 4 --headless -u 400 -r 40 -t 60s
Locust also offers --processes 4, which starts the workers for you on one machine.
Exercise 2. The master says “Waiting for workers to be ready, 1 of 2 connected” and never starts. What do you check?
Solution
One worker has not connected: check that it was started, uses --worker with the correct --master-host, can reach
the master’s port 5557 (firewall), and runs the same Locust version.
Exercise 3. You doubled the workers but the total requests per second did not change. Name two likely reasons.
Solution
(1) The service under test is the bottleneck, so it cannot go faster however much load you send. (2) The users
spend most of their time waiting (wait_time) rather than sending, so adding workers without adding users
changes nothing. Check the server’s CPU and the number of users.
Practice#
Take the Session 8 quiz. The original page Running Locust in Distributed Mode is in the reference section.