← Back to skills
extension
Category: Development & EngineeringAPI key requirement unconfirmed

locust

Locust load testing in Python. Use for load testing.

personAuthor: jakexiaohubgithub

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:

# 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