Skip to content

Locust — Architecture & Basics

What Locust Is

Locust is an open-source load testing tool where test scenarios are written in plain Python. No DSLs, no XML configs. A Locust file is a Python script.


Architecture

Event-Driven Core (gevent)

Locust uses gevent — a coroutine-based concurrency library built on greenlets.

  • Each simulated user runs in its own greenlet (lightweight coroutine)
  • Thousands of users can run concurrently on a single machine without threading overhead
  • HTTP requests are non-blocking — while one user waits for a response, others proceed
Master process
    └── Greenlet: User 1 → request → wait → request
    └── Greenlet: User 2 → request → wait → request
    └── Greenlet: User 3 → request → wait → request
    ... (thousands)

Distributed Mode (Master / Worker)

For generating large load beyond a single machine's capacity:

Master (coordinates, aggregates metrics)
    ├── Worker 1 (runs N users)
    ├── Worker 2 (runs N users)
    └── Worker 3 (runs N users)

Workers receive test configuration from master and report metrics back. The master aggregates all metrics and exposes the web UI.


Core Concepts

User

Represents one simulated real user. Each user: - Has its own session (cookies, headers, state) - Executes tasks in sequence - Waits between tasks (think time)

Task

A single action a user performs — typically one HTTP request or a business flow step.

@task
def view_product(self) -> None:
    self.client.get("/products/42")

Tasks can have weights to model realistic traffic distribution:

@task(3)  # called 3x more often than weight-1 tasks
def browse(self) -> None:
    self.client.get("/products")

@task(1)
def checkout(self) -> None:
    self.client.post("/orders")

Wait Time

Think time between tasks — simulates real user behavior (reading a page, filling a form).

Strategy Usage
between(1, 3) Random delay between 1–3 seconds
constant(2) Fixed 2 second delay
constant_throughput(10) Target 10 task executions per second per user

Minimal Example

from locust import HttpUser, task, between


class ShopUser(HttpUser):
    wait_time = between(1, 3)
    host = "https://example.com"

    @task(3)
    def browse_products(self) -> None:
        self.client.get("/products")

    @task(1)
    def view_cart(self) -> None:
        self.client.get("/cart")

Run it:

locust -f locustfile.py --headless -u 100 -r 10 --run-time 60s
Flag Meaning
-u 100 Spawn 100 total users
-r 10 Spawn 10 users per second (ramp-up rate)
--run-time 60s Stop after 60 seconds
--headless No web UI, results in terminal