Verwendung
- Installationsbefehl kopieren und das Quellpaket vor der Installation in der eigenen Agentenumgebung prüfen.
- Benötigte Werkzeuge, Zugangsdaten und Hosts im Original prüfen.
- Eingabe und gewünschtes Ergebnis beschreiben und die Ausgabe mit den Quellen abgleichen.
npx skills add https://github.com/TerminalSkills/skills --skill locustVor dem Start
- Die Installation umfasst weder Modellabo noch API-Kontingent oder Dateizugriffsrechte.
- Sterne und Installationen zeigen Aktivität, keine unabhängige Qualitäts- oder Sicherheitsprüfung.
Aus dem Quell-Repository gerendert; Überschriften, Beispiele, Code, Tabellen, Links und Bilder bleiben erhalten.
Locust
Overview
Locust defines simulated users as Python classes in a locustfile.py. Each user runs weighted @task methods with a wait time between them. Run it with the web UI (default, http://localhost:8089) to start and watch a test, or with --headless in CI. It scales out with --processes on one machine or a master plus workers across machines. Checked against Locust 2.46.7 (October 2026), which needs Python 3.11 or newer.
Instructions
Install and run
python -m venv .venv && source .venv/bin/activate
pip install locust
locust --version
locust -f locustfile.py # web UI on http://localhost:8089Basic locustfile
# locustfile.py: users browse the catalog and add to cart
import os
from locust import HttpUser, task, between
class ShopUser(HttpUser):
host = "https://staging.shop.internal"
wait_time = between(1, 3)
def on_start(self):
# runs once per simulated user
resp = self.client.post("/login", json={"username": os.environ["LOAD_USER"], "password": os.environ["LOAD_USER_PASSWORD"]})
self.client.headers["Authorization"] = f"Bearer {resp.json()['token']}"
@task(3)
def browse_products(self):
self.client.get("/products")
@task(2)
def view_product(self):
# group URLs with ids under one stats row; mark custom failures
with self.client.get("/products/1", name="/products/[id]", catch_response=True) as resp:
if resp.status_code != 200:
resp.failure(f"unexpected status {resp.status_code}")
@task(1)
def add_to_cart(self):
self.client.post("/cart", json={"product_id": 1, "quantity": 1})Read credentials from environment variables (os.environ["LOAD_USER_PASSWORD"]) rather than hard-coding them. FastHttpUser (gevent-based client, much higher requests per CPU core) is a drop-in choice when the load generator is the bottleneck, but its client has no .headers attribute: pass headers= per request instead.
Headless runs and CI
locust -f locustfile.py --headless -u 50 -r 10 -t 2m \
--csv results --html report.html --only-summary-u is peak users, -r the spawn rate per second, -t the run time. --autostart starts the test immediately but keeps the web UI; --autoquit 10 exits 10 seconds after the run. --json prints final stats as JSON. Settings can also live in a locust.conf file or --config.
Locust exits with code 1 when the run contains any failed request (--exit-code-on-error <int> sets that code, default 1; 0 disables it), so a plain headless run already fails the pipeline. To allow a tolerated error rate instead, pass --exit-code-on-error 0 and set environment.process_exit_code in a test_stop listener (see Example 2).
Custom load shapes
Put a LoadTestShape subclass in the locustfile (or a second file passed as -f a.py,b.py). When one exists, -u/-r are ignored. Returning None from tick() ends the test.
from locust import LoadTestShape
class DailyTrafficShape(LoadTestShape):
stages = [
{"duration": 60, "users": 20, "spawn_rate": 5},
{"duration": 180, "users": 200, "spawn_rate": 20}, # cumulative end times, in seconds
{"duration": 240, "users": 0, "spawn_rate": 20},
]
def tick(self):
run_time = self.get_run_time()
for stage in self.stages:
if run_time < stage["duration"]:
return (stage["users"], stage["spawn_rate"])
return NoneHere duration is the time since the start at which a stage ends, not its length.
Distributed testing
# one machine, all cores: forks one worker per core
locust -f locustfile.py --processes -1
# several machines
locust -f locustfile.py --master --expect-workers 4 # coordinator, web UI
locust -f locustfile.py --worker --master-host 10.0.4.12 # on each worker
locust -f locustfile.py --master --headless -u 1000 -r 50 -t 5m --expect-workers 4 # headlessWorkers need the locustfile and its dependencies locally (a worker started with -f - downloads the file from the master). Add --enable-rebalancing so users are redistributed when workers join late.
Event hooks
Request listeners receive keyword arguments (request_type, name, response_time, response_length, exception, context, response, ...), so always accept **kwargs.
Examples
Example 1: Smoke test an API before a release
Request: "Hit our staging orders API with 20 users for a minute and give me an HTML report."
locust -f locustfile.py --headless -u 20 -r 5 -t 1m \
--host https://staging.shop.internal --html orders-report.html --only-summaryResult: a table with one row per request name (GET /products, POST /cart, ...) showing request counts, failures, average and percentile response times, plus orders-report.html with charts.
Example 2: Fail CI when the error rate is too high
Request: "Fail the pipeline if more than 1% of requests fail."
# add to locustfile.py
from locust import events
@events.test_stop.add_listener
def check_error_rate(environment, **kwargs):
if environment.stats.total.fail_ratio > 0.01:
environment.process_exit_code = 1locust -f locustfile.py --headless -u 50 -r 10 -t 2m --csv results --exit-code-on-error 0
echo $? # 1 only when the error rate is above 1%A GitHub Actions job runs the same command after pip install locust and uploads results_*.csv with actions/upload-artifact.
Guidelines
- Name dynamic URLs (
name="/products/[id]") or the stats table gets one row per id. - An exception in
on_startor a task stops that simulated user silently while the run continues; read the log for tracebacks, not only the summary. - Run the load generator on a different machine from the target, and watch generator CPU (keep it under about 90%); add workers or switch to
FastHttpUserif it saturates. - Test staging with test accounts, never production with real customer data, and get permission before load testing a service you do not own.
- Pass
--reset-statsto drop the ramp-up period from the numbers. - Response times in the stats are request latency only; locust cannot see server CPU, so monitor the target separately.

