Pular para o conteúdo

Locust Load Testing Cheatsheet

Locust Load Testing Cheatsheet

Installation

PlatformCommand
Ubuntu/Debiansudo 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/CentOSsudo yum install python3 python3-pip
python3 -m venv locust-env && source locust-env/bin/activate
pip install locust
macOSbrew install python3
python3 -m venv locust-env && source locust-env/bin/activate
pip install locust
Windowspython -m venv locust-env
locust-env\Scripts\activate
pip install locust
Dockerdocker pull locustio/locust
docker run -p 8089:8089 -v $PWD:/mnt/locust locustio/locust -f /mnt/locust/locustfile.py
Specific Versionpip install locust==2.17.0
With Dev Dependenciespip install locust[dev]
Verify Installationlocust --version

Basic Commands

CommandDescription
locust -f locustfile.pyStart Locust with web UI on default port 8089
locust -f locustfile.py --host=https://api.example.comStart with specific target host
locust -f locustfile.py --headless -u 100 -r 10Run headless mode with 100 users, spawn rate 10/sec
locust -f locustfile.py --headless -u 500 -r 50 -t 30mRun for 30 minutes with 500 users
locust -f locustfile.py --web-port 8090Start web UI on custom port 8090
locust -f locustfile.py --web-host 0.0.0.0Bind web UI to all network interfaces
locust -f locustfile.py --headless -u 100 -r 10 -t 10m --csv=resultsSave statistics to CSV files
locust -f locustfile.py --headless -u 100 -r 10 -t 5m --html=report.htmlGenerate HTML report after test
locust -f locustfile.py --loglevel DEBUGSet logging level to DEBUG
locust -f locustfile.py --logfile=locust.logWrite logs to file
locust -f locustfile.py --headless -u 100 -r 10 WebsiteUserRun specific user class only
locust -f locustfile.py --headless -u 100 -r 10 WebUser MobileUserRun multiple user classes
locust -f locustfile1.py -f locustfile2.pyLoad multiple locustfiles
locust -f tests.performance.load_testUse Python module path instead of file
locust --versionDisplay Locust version
locust --helpShow all available command-line options

Advanced Usage

CommandDescription
locust -f locustfile.py --masterStart master node for distributed testing
locust -f locustfile.py --worker --master-host=192.168.1.100Start worker node connecting to master
locust -f locustfile.py --master --expect-workers=4Start master expecting 4 workers before beginning
locust -f locustfile.py --master --master-bind-host=0.0.0.0 --master-bind-port=5557Master with custom bind address and port
locust -f locustfile.py --worker --master-host=localhost --master-port=5557Worker with custom master port
locust -f locustfile.py --headless -u 1000 -r 100 WebUser:3 APIUser:1Run with weighted user classes (75% WebUser, 25% APIUser)
locust -f locustfile.py --step-load --step-users 100 --step-time 60sEnable step load mode (increment users every 60s)
locust -f locustfile.py --tags critical --exclude-tags slowRun only tasks tagged as ‘critical’, exclude ‘slow’
locust -f locustfile.py --config=locust.confLoad configuration from file
locust -f locustfile.py --reset-statsReset statistics during test run
locust -f locustfile.py --stop-timeout=60Set graceful shutdown timeout to 60 seconds
locust -f locustfile.py --modern-uiEnable modern web UI interface
locust -f locustfile.py --headless -u 100 -r 10 --jsonOutput statistics in JSON format
locust -f locustfile.py --headless -u 100 -r 10 --timeout=30Set connection timeout to 30 seconds
locust -f locustfile.py --headless -u 100 -r 10 --run-time 1hRun for exactly 1 hour then stop
docker-compose up --scale worker=4Scale 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

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