Skip to content

Locust Load Testing Cheatsheet

Installation

Platform Command
Ubuntu/Debian sudo apt-get update && sudo apt-get install python3 python3-pip python3-venv
python3 -m venv locust-env && source locust-env/bin/activate
pip install locust
RHEL/CentOS sudo yum install python3 python3-pip
python3 -m venv locust-env && source locust-env/bin/activate
pip install locust
macOS brew install python3
python3 -m venv locust-env && source locust-env/bin/activate
pip install locust
Windows python -m venv locust-env
locust-env\Scripts\activate
pip install locust
Docker docker pull locustio/locust
docker run -p 8089:8089 -v $PWD:/mnt/locust locustio/locust -f /mnt/locust/locustfile.py
Specific Version pip install locust==2.17.0
With Dev Dependencies pip install locust[dev]
Verify Installation locust --version

Basic Commands

Command Description
locust -f locustfile.py Start Locust with web UI on default port 8089
locust -f locustfile.py --host=https://api.example.com Start with specific target host
locust -f locustfile.py --headless -u 100 -r 10 Run headless mode with 100 users, spawn rate 10/sec
locust -f locustfile.py --headless -u 500 -r 50 -t 30m Run for 30 minutes with 500 users
locust -f locustfile.py --web-port 8090 Start web UI on custom port 8090
locust -f locustfile.py --web-host 0.0.0.0 Bind web UI to all network interfaces
locust -f locustfile.py --headless -u 100 -r 10 -t 10m --csv=results Save statistics to CSV files
locust -f locustfile.py --headless -u 100 -r 10 -t 5m --html=report.html Generate HTML report after test
locust -f locustfile.py --loglevel DEBUG Set logging level to DEBUG
locust -f locustfile.py --logfile=locust.log Write logs to file
locust -f locustfile.py --headless -u 100 -r 10 WebsiteUser Run specific user class only
locust -f locustfile.py --headless -u 100 -r 10 WebUser MobileUser Run multiple user classes
locust -f locustfile1.py -f locustfile2.py Load multiple locustfiles
locust -f tests.performance.load_test Use Python module path instead of file
locust --version Display Locust version
locust --help Show all available command-line options

Advanced Usage

Command Description
locust -f locustfile.py --master Start master node for distributed testing
locust -f locustfile.py --worker --master-host=192.168.1.100 Start worker node connecting to master
locust -f locustfile.py --master --expect-workers=4 Start master expecting 4 workers before beginning
locust -f locustfile.py --master --master-bind-host=0.0.0.0 --master-bind-port=5557 Master with custom bind address and port
locust -f locustfile.py --worker --master-host=localhost --master-port=5557 Worker with custom master port
locust -f locustfile.py --headless -u 1000 -r 100 WebUser:3 APIUser:1 Run with weighted user classes (75% WebUser, 25% APIUser)
locust -f locustfile.py --step-load --step-users 100 --step-time 60s Enable step load mode (increment users every 60s)
locust -f locustfile.py --tags critical --exclude-tags slow Run only tasks tagged as 'critical', exclude 'slow'
locust -f locustfile.py --config=locust.conf Load configuration from file
locust -f locustfile.py --reset-stats Reset statistics during test run
locust -f locustfile.py --stop-timeout=60 Set graceful shutdown timeout to 60 seconds
locust -f locustfile.py --modern-ui Enable modern web UI interface
locust -f locustfile.py --headless -u 100 -r 10 --json Output statistics in JSON format
locust -f locustfile.py --headless -u 100 -r 10 --timeout=30 Set connection timeout to 30 seconds
locust -f locustfile.py --headless -u 100 -r 10 --run-time 1h Run for exactly 1 hour then stop
docker-compose up --scale worker=4 Scale distributed test to 4 workers using Docker Compose

Configuration

Configuration File (locust.conf)

# locust.conf - Configuration file format
locustfile = locustfile.py
host = https://api.example.com
users = 1000
spawn-rate = 100
run-time = 30m
headless = true
csv = results
html = report.html
loglevel = INFO
logfile = locust.log

Basic Locustfile Structure

# locustfile.py - Minimal example
from locust import HttpUser, task, between

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

    @task
    def index_page(self):
        self.client.get("/")

    @task(3)  # 3x more likely than other tasks
    def view_item(self):
        self.client.get("/item/123")

Advanced Locustfile with Authentication

from locust import HttpUser, task, between
import random

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

    def on_start(self):
        """Called when user starts - login here"""
        response = self.client.post("/login", json={
            "username": "testuser",
            "password": "password123"
        })
        self.token = response.json()["token"]

    @task
    def protected_endpoint(self):
        headers = {"Authorization": f"Bearer {self.token}"}
        self.client.get("/api/protected", headers=headers)

    @task(2)
    def create_resource(self):
        headers = {"Authorization": f"Bearer {self.token}"}
        self.client.post("/api/items", 
                        json={"name": "Test", "value": random.randint(1, 100)},
                        headers=headers)

Custom Load Shape

from locust import LoadTestShape

class StagesLoadShape(LoadTestShape):
    """
    Custom load pattern with stages:
    - Ramp to 100 users over 60s
    - Hold at 100 for 120s
    - Ramp to 500 over 60s
    - Hold at 500 for 180s
    """
    stages = [
        {"duration": 60, "users": 100, "spawn_rate": 10},
        {"duration": 180, "users": 100, "spawn_rate": 10},
        {"duration": 240, "users": 500, "spawn_rate": 50},
        {"duration": 420, "users": 500, "spawn_rate": 50},
    ]

    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 None

Docker Compose Configuration

# docker-compose.yml - Distributed testing setup
version: '3'

services:
  master:
    image: locustio/locust
    ports:
      - "8089:8089"
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/locustfile.py --master --expect-workers=4

  worker:
    image: locustio/locust
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/locustfile.py --worker --master-host=master

Environment Variables

# Set environment variables for Locust
export LOCUST_LOCUSTFILE=locustfile.py
export LOCUST_HOST=https://api.example.com
export LOCUST_USERS=1000
export LOCUST_SPAWN_RATE=100
export LOCUST_RUN_TIME=30m
export LOCUST_HEADLESS=true

# Run with environment variables
locust

Common Use Cases

Use Case 1: API Load Testing with Authentication

# Create locustfile for API testing
cat > api_test.py << 'EOF'
from locust import HttpUser, task, between

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

    def on_start(self):
        # Authenticate once per user
        response = self.client.post("/api/auth/login", json={
            "username": "testuser",
            "password": "testpass"
        })
        self.token = response.json()["access_token"]

    @task(3)
    def get_users(self):
        self.client.get("/api/users", 
                       headers={"Authorization": f"Bearer {self.token}"})

    @task(1)
    def create_user(self):
        self.client.post("/api/users",
                        json={"name": "New User", "email": "test@example.com"},
                        headers={"Authorization": f"Bearer {self.token}"})
EOF

# Run the test
locust -f api_test.py --headless --host=https://api.example.com \
  -u 500 -r 50 -t 10m --html=api_report.html

Use Case 2: Distributed Load Testing Across Multiple Machines

# On master machine (192.168.1.100)
locust -f locustfile.py --master --master-bind-host=0.0.0.0 \
  --expect-workers=3 --web-host=0.0.0.0

# On worker machine 1
locust -f locustfile.py --worker --master-host=192.168.1.100

# On worker machine 2
locust -f locustfile.py --worker --master-host=192.168.1.100

# On worker machine 3
locust -f locustfile.py --worker --master-host=192.168.1.100

# Access web UI from any machine
# http://192.168.1.100:8089

Use Case 3: CI/CD Integration with Automated Testing

# Create test script for CI/CD pipeline
cat > run_load_test.sh << 'EOF'
#!/bin/bash

# Run load test and capture exit code
locust -f locustfile.py --headless \
  --host=https://staging.example.com \
  -u 1000 -r 100 -t 5m \
  --html=report.html \
  --csv=results \
  --exit-code-on-error 1

# Check if test passed
if [ $? -eq 0 ]; then
    echo "Load test passed"
    exit 0
else
    echo "Load test failed"
    exit 1
fi
EOF

chmod +x run_load_test.sh
./run_load_test.sh

Use Case 4: Testing with Multiple User Scenarios

# Create multi-scenario locustfile
cat > multi_scenario.py << 'EOF'
from locust import HttpUser, task, between

class BrowserUser(HttpUser):
    weight = 3  # 75% of users
    wait_time = between(2, 5)

    @task
    def browse_pages(self):
        self.client.get("/")
        self.client.get("/products")
        self.client.get("/about")

class MobileUser(HttpUser):
    weight = 1  # 25% of users
    wait_time = between(1, 3)

    @task
    def mobile_api(self):
        self.client.get("/api/mobile/products")

class AdminUser(HttpUser):
    weight = 0.1  # Very few admin users
    wait_time = between(5, 10)

    def on_start(self):
        self.client.post("/admin/login", json={
            "username": "admin", "password": "admin123"
        })

    @task
    def admin_dashboard(self):
        self.client.get("/admin/dashboard")
EOF

# Run with all user types
locust -f multi_scenario.py --headless -u 1000 -r 100 -t 15m

Use Case 5: Step Load Testing with Progressive Ramps

# Create step load configuration
cat > step_load.py << 'EOF'
from locust import HttpUser, task, between, LoadTestShape

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

    @task
    def load_page(self):
        self.client.get("/")

class StepLoadShape(LoadTestShape):
    step_time = 120  # 2 minutes per step
    step_load = 100  # Add 100 users per step
    spawn_rate = 10
    time_limit = 600  # 10 minutes total

    def tick(self):
        run_time = self.get_run_time()

        if run_time > self.time_limit:
            return None

        current_step = run_time // self.step_time
        return (current_step + 1) * self.step_load, self.spawn_rate
EOF

# Run step load test
locust -f step_load.py --headless --host=https://example.com \
  --html=step_load_report.html

Best Practices

  • Use realistic wait times: Set wait_time = between(1, 5) to simulate real user behavior with pauses between actions, avoiding unrealistic constant hammering
  • Implement proper authentication: Use on_start() method to authenticate once per user rather than on every request, reducing overhead and mimicking real sessions
  • Tag your tasks: Use @tag('critical', 'api') decorators to organize tests and run specific subsets during development or targeted testing
  • Monitor resource usage: Watch CPU and memory on both Locust machines and target servers; Locust workers should use <80% CPU for accurate results
  • Start with small loads: Begin tests with 10-50 users to verify test logic works correctly before scaling to thousands of concurrent users
  • Use distributed mode for scale: Single machine limited to ~5000-10000 users; use master-worker setup to simulate larger loads across multiple machines
  • Implement proper error handling: Use response.failure() to mark failed requests and catch exceptions to prevent test crashes from stopping load generation
  • Version control your tests: Store locustfiles in Git alongside application code, treating performance tests as first-class citizens in your testing strategy
  • Set realistic spawn rates: Don't spawn all users instantly; use gradual ramp-up (10-100 users/sec) to avoid overwhelming systems and getting false failures
  • Generate reports for analysis: Always use --html and --csv flags to capture results for post-test analysis and historical comparison

Troubleshooting

Issue Solution
ImportError: No module named 'locust' Ensure virtual environment is activated: source locust-env/bin/activate then reinstall: pip install locust
Workers not connecting to master Check firewall allows port 5557, verify master IP address is correct, ensure both master and worker use same locustfile
Connection refused errors during test Target server may be down or blocking requests; check server logs, verify host URL is correct, ensure firewall allows traffic
Locust using 100% CPU on worker Reduce number of users per worker (max ~5000), add more worker machines, or optimize locustfile to reduce processing overhead
Statistics not updating in web UI Check browser console for errors, try different browser, ensure no proxy/firewall blocking WebSocket connections on port 8089
gevent installation fails on Windows Install Visual C++ Build Tools from Microsoft, or use pre-compiled wheels: pip install --only-binary :all: gevent
Test results inconsistent/unreliable Ensure workers have sufficient resources, check network latency between workers and target, verify spawn rate isn't too aggressive
SSL: CERTIFICATE_VERIFY_FAILED errors Disable SSL verification (testing only): self.client.verify = False in on_start(), or provide certificate bundle path
Memory usage grows continuously Check for memory leaks in locustfile (storing too much data), restart workers periodically, or reduce test duration
Cannot bind to port 8089 Port already in use; use --web-port 8090 to use different port, or kill existing Locust process: pkill -f locust
Docker container exits immediately Ensure locustfile path is correct in volume mount, check container logs: docker logs <container_id>, verify command syntax
Tasks not running in expected order Use SequentialTaskSet for ordered execution instead of random task selection, or implement custom task scheduling logic