Skip to content

Advanced Locust Usage

Distributed Testing

A single machine can typically simulate 500–5000 users (depends on wait time and request speed). For larger scale, use distributed mode.

Start master

locust -f locustfile.py --master --expect-workers=3

Start workers (on same or different machines)

locust -f locustfile.py --worker --master-host=192.168.1.10

Workers receive user class definitions from master. Each worker runs a slice of total users. Master aggregates all metrics.

Docker Compose example

services:
  master:
    image: locustio/locust
    ports: ["8089:8089"]
    volumes: [".:/mnt/locust"]
    command: -f /mnt/locust/locustfile.py --master

  worker:
    image: locustio/locust
    volumes: [".:/mnt/locust"]
    command: -f /mnt/locust/locustfile.py --worker --master-host=master
    deploy:
      replicas: 4

Custom Metrics

Locust's built-in metrics cover HTTP requests. For custom business KPIs, use events.

import time
from locust import HttpUser, task, between, events


class BusinessUser(HttpUser):
    wait_time = between(1, 2)

    @task
    def place_order(self) -> None:
        start = time.perf_counter()
        resp = self.client.post("/orders", json={"item": "widget"})
        elapsed = (time.perf_counter() - start) * 1000

        events.request.fire(
            request_type="BUSINESS",
            name="place_order_flow",
            response_time=elapsed,
            response_length=len(resp.content),
            exception=None if resp.ok else Exception(resp.status_code),
        )

Custom events appear in Locust's metrics table alongside HTTP metrics.


Event Hooks

Locust exposes hooks for setup, teardown, and per-request logic.

Test initialization

from locust import events
from locust.env import Environment


@events.test_start.add_listener
def on_test_start(environment: Environment, **kwargs: object) -> None:
    print("Test started — warming up caches")


@events.test_stop.add_listener
def on_test_stop(environment: Environment, **kwargs: object) -> None:
    print("Test finished — exporting results")

Per-request logging

@events.request.add_listener
def on_request(
    request_type: str,
    name: str,
    response_time: float,
    response_length: int,
    exception: Exception | None,
    **kwargs: object,
) -> None:
    if exception:
        print(f"FAILURE {name}: {exception}")
    elif response_time > 1000:
        print(f"SLOW {name}: {response_time:.0f}ms")

Shape Classes — Programmatic Load Control

For complex load patterns, use LoadTestShape:

from locust import LoadTestShape


class StepLoadShape(LoadTestShape):
    stages = [
        {"duration": 60, "users": 10, "spawn_rate": 5},
        {"duration": 120, "users": 50, "spawn_rate": 10},
        {"duration": 180, "users": 100, "spawn_rate": 20},
        {"duration": 240, "users": 200, "spawn_rate": 50},
    ]

    def tick(self) -> tuple[int, float] | None:
        run_time = self.get_run_time()
        for stage in self.stages:
            if run_time < stage["duration"]:
                return stage["users"], stage["spawn_rate"]
        return None

tick() is called every second. Return None to end the test.