SuperAPI AI Directory

locust

Testing & quality

View repository

Updated 10-15 21:49

About this skill

Locust

Locust is an easy-to-use, scriptable, and scalable performance testing tool. You define the behavior of your users in regular Python code.

When to Use

  • Python-Based Load & Performance Testing: Authoring complex, dynamic load test scenarios using standard Python code.
  • Distributed Master/Worker Scaling: Scaling load generation across dozens of distributed worker machines easily.
  • Real-Time Web Dashboard Monitoring: Inspecting request per second, response latency charts, and failures live in the Locust browser UI.
  • Custom Protocol Testing: Load testing gRPC, WebSockets, or proprietary TCP protocols alongside standard HTTP.

Quick Start

from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
    wait_time = between(1, 5)
@task
def index(self):
    self.client.get("/")

@task(3)
def view_item(self):
    item_id = randint(1, 10000)
    self.client.get(f"/item?id={item_id}", name="/item")

Run `locust -f locustfile.py`.

## Core Concepts

### User Classes & Task Hierarchy

Defines virtual user behaviors using Python methods annotated with `@task`:

```python
# locustfile.py
from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
    wait_time = between(1, 3) # Wait 1-3 seconds between tasks

    def on_start(self):
        # Executed when virtual user spawns (e.g. login)
        res = self.client.post("/api/login", json={"user": "test", "pass": "secret"})
        self.token = res.json().get("token")
        self.client.headers = {"Authorization": f"Bearer {self.token}"}

    @task(3) # Weight 3: executed 3x more often
    def view_catalog(self):
        self.client.get("/api/catalog")

    @task(1) # Weight 1
    def place_order(self):
        self.client.post("/api/checkout", json={"itemId": 42})

Headless CI/CD Execution with Thresholds

Runs headlessly in build pipelines, exiting with non-zero status codes if criteria fail:

locust --headless \
  -u 200 -r 20 -t 5m \
  --host https://staging.example.com \
  --csv=results \
  --exit-code-on-error 1

Distributed Master / Worker Architecture

Coordinates load across multiple machines:

# Start Master node
locust --master

# Start Worker nodes (across cluster)
locust --worker --master-host=10.0.1.5

Common Patterns

Weighted Task Set with User Session Management

Problem: Real users perform actions with variable frequencies and stateful session contexts.

Solution: Use @task(weight) with HttpUser:

from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
    wait_time = between(1, 3)

    @task(5)
    def browse_catalog(self):
        self.client.get("/products")

    @task(1)
    def checkout_cart(self):
        self.client.post("/cart/checkout", json={"items": [1, 2]})

Best Practices

Do:

  • Use Weights on @task(weight): Reflect realistic user activity ratios (e.g. 10 browsing actions for every 1 checkout action).
  • Run Headless in CI/CD: Use --headless mode to automate performance checks in GitHub Actions or GitLab CI.
  • Group Dynamic URLs with name Parameters: Group /users/1 and /users/2 under a single endpoint name: self.client.get("/users/1", name="/users/[id]").
  • Use FastHttpUser for High Concurrency: Inherit from FastHttpUser (geventhttpclient) for 5-6x higher throughput per worker CPU.

Don't:

  • Perform heavy computational blocking in tasks: Keep task code lean to prevent starving the gevent cooperative thread loop.
  • Run single-process tests for heavy loads: Spawn multiple worker processes (--processes 4) to leverage multi-core CPUs.
  • Forget SSL verification options: Pass verify=False only in isolated dev environments; never bypass security in prod.

Troubleshooting

Error Cause Solution
ConnectionRefusedError / Max retries exceeded Target server port closed or refused incoming connections. Ensure target application is running and accessible on specified host.
Too many open files (OSError) OS file descriptor limit exceeded on Locust worker. Increase file limit using ulimit -n 65536.
CatchResponseError: status 500 Target server throwing internal server exceptions under load. Check application error logs and stack traces on target server.

References