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 |