Locust

Where Locust helps QA and how its Python-first approach makes performance scenarios transparent and manageable.

Updated:

Contents

Locust describes load scenarios in Python. Virtual users perform tasks, send requests, and observe configured waits. This suits teams already maintaining Python code that want to express complex user journeys as ordinary functions that are easy to review.

Readable code does not guarantee a correct model. A scenario may work technically while measuring login instead of ordering, sharing one object among all users, or reaching generator limits. QA must verify the meaning of the load and how statistics relate to actual service behavior.

What a user models

HttpUser provides an HTTP client. Each user has its own instance and session state. Tasks are selected according to weights, while wait_time controls waits between executions. The standard model represents users who wait for their actions to finish.

When responses slow, the same users start fewer new tasks per second. User count therefore differs from RPS, and spawn-rate controls user startup rather than HTTP request rate. An independent external operation stream requires separate validation of the chosen model and achieved intensity.

Preparing the test contract

Consider your own catalog: GET /api/catalog should return 200 and an object containing an items array. The operation is read-only, so a small trial creates no orders and needs no complex cleanup. This is an example condition rather than an inherent property of every GET endpoint.

Record catalog size, cache state, and environment limits. Define erroneous responses and acceptable latency. Set a finite timeout so a hanging request does not occupy a user indefinitely and make the load profile unpredictable.

A minimal locustfile

Save the code in locustfile.py in an environment with Locust installed. catch_response lets you mark a technically successful HTTP response as failed when its content violates the contract. The example explicitly checks status, JSON, and collection type.

python
from locust import HttpUser, task, between

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

    @task
    def catalog(self):
        with self.client.get(
            "/api/catalog", name="catalog", timeout=5,
            catch_response=True
        ) as response:
            if response.status_code != 200:
                response.failure("Unexpected status")
                return
            try:
                payload = response.json()
            except ValueError:
                response.failure("Invalid JSON")
                return
            if not isinstance(payload, dict) or not isinstance(
                payload.get("items"), list
            ):
                response.failure("items must be an array")
shell
locust -f locustfile.py --headless -u 5 -r 1 -t 1m --host https://qa.example.test --csv run01

Replace the domain with the authorized test environment's address. The command starts up to five users, adding one per second, and saves CSV files with the specified prefix. This checks mechanics; before scaling up, confirm that every request performs the intended operation.

Multiple tasks and weights

Adding product views and searches with different weights makes Locust choose tasks with the corresponding probabilities. This does not promise exact proportions in a small run: randomness and different action durations affect actual counts.

For a sequential business journey, group related actions in one task or use a suitable scenario structure. Independently choosing “create cart” and “pay” at random without shared state does not model a buyer. Check actual operation proportions in the report.

Sessions and correlation

Authenticate when a user starts and retain the current token in that user's state. The HTTP client preserves cookies between requests. Avoid logging in before every read unless real users do so; otherwise, you model a different authorization-service load share.

Extract a created cart's ID from the response and use it in the next step. Stop the chain meaningfully after failed login or a missing ID. Numerous secondary 401 or 404 errors must not conceal the original user-setup failure.

Data and metric names

Use a meaningful distribution of products and search queries for reads. One popular product tests a hot cache path, which is useful when explicitly identified. It does not establish search behavior across a large, varied catalog.

Group dynamic URLs through name so every ID does not create a separate statistics row. Preserve the ability to investigate particular errors without recording secrets. For state-changing operations, plan unique data, final-state checks, and safe cleanup.

Resources and distributed execution

Monitor generator CPU, memory, and networking. Arbitrary Python code, heavy response parsing, or an incompatible blocking library can disrupt expected user execution. Rising latency requires distinguishing generation issues from server problems.

Distributed runs require identical scenarios and dependencies on worker nodes. Check data distribution separately so processes do not incorrectly share mutable records. Additional workers help only after identifying a generator constraint; they cannot fix an incorrect model or contract.

Assessing results

Examine achieved intensity, content errors, latency distributions, and trends. Correlate them with connection pools, CPU, memory, queues, and database waits. Low average latency with widespread fast rejections does not indicate success.

CLI execution and CSV output do not themselves enforce every business acceptance threshold. Configure explicit criteria through supported events or subsequent result analysis for automated decisions. Version those rules with the scenario so runs are assessed consistently.

Mistakes and useful reporting

Common mistakes include treating spawn-rate as requests per second, leaving validation exceptions unhandled, comparing different profiles through one average, and overloading the generator with data preparation. A one-minute exercise cannot establish long-term stability.

A useful report shows the scenario, conditions, achieved traffic, result correctness, and reasons for violated criteria. For the catalog, expect a valid items array in every accepted response and compliance with agreed thresholds. State cache, data, and environment limitations beside the conclusion so the team can apply it correctly.

Further reading