Distributed Load Testing with Locust
How to run Locust in distributed mode across multiple machines, and the practical considerations for scaling beyond a single node.
Locust’s distributed mode follows a master/worker architecture, conceptually similar to JMeter’s controller/remote-engine model, but designed to be lightweight to set up from the start rather than requiring separate manual server-process steps on each machine.
Starting a master and workers
# On the master node:
locust -f locustfile.py --master
# On each worker node:
locust -f locustfile.py --worker --master-host=<master-ip>
The master coordinates test configuration (user count, spawn rate, started via its web UI or via CLI flags) and aggregates results from all connected workers; each worker actually generates load by spawning simulated users locally.
How load gets distributed across workers
The master divides the configured total user count evenly across connected workers — if you start 1,000 users with 10 workers connected, each worker runs roughly 100. This means worker count and per-worker capacity both factor into your achievable total load, same consideration as load generator sizing in any distributed testing tool.
Running workers as containers
Because Locust workers are just Python processes, containerizing them (a worker Docker image, scaled via Kubernetes or a similar orchestrator to however many replicas you need) is a natural way to scale up or down for a given test’s needs without manually provisioning individual machines — a common pattern for teams that already have container orchestration infrastructure and want load generation to use the same tooling.
Network and firewall considerations
Master and workers communicate over a specific port (default 5557) — make sure this is open between all nodes, the same category of “obvious port open but the coordination port isn’t” mistake covered for JMeter’s distributed mode.
Aggregated results and per-worker visibility
The master’s web UI shows combined, aggregated statistics across all workers by default; if you need to diagnose whether one specific worker is underperforming (e.g. on a slower network path or undersized machine), you’ll need to check that worker’s own local resource usage directly, since the master’s UI doesn’t break down results per-worker by default.
A note on data parameterization across workers
Same caution as JMeter and LoadRunner’s distributed modes: if your Locust script reads from a local test-data file, each worker reads its own copy independently — without deliberately partitioning data across workers (or fetching data from a shared external source instead of a local file), you risk unintended duplication across the cluster.
When distributed mode is actually necessary
A single modern machine running Locust (gevent-based, lightweight per-user) can often simulate several thousand concurrent users before becoming the bottleneck — confirm you’ve actually hit a real single-machine ceiling (CPU, network) before assuming you need distributed mode, the same “verify, don’t assume” principle covered for JMeter and LoadRunner distributed testing.
Takeaway: Locust’s master/worker setup is lighter-weight to stand up than JMeter’s or LoadRunner’s distributed modes, especially if you already have container orchestration — but the same data-partitioning and capacity-verification considerations apply regardless of tool.
Comments are powered by Giscus (GitHub Discussions). Enable them by
configuring GISCUS in src/consts.ts — see
giscus.app.