Locust’s CSV stats are actually a log of every single request, not just a summary, and that’s why they’re so powerful for deep dives.
Imagine you’re running a load test and you want to see not just the average response time, but exactly when certain requests started taking longer, or which specific requests failed. Locust’s CSV output gives you this granular data.
Let’s say you’ve run a test and want to export the stats. You’ll find them in your Locust working directory after the test finishes, typically in files named stats_history.csv and stats.csv.
Here’s what they contain:
stats_history.csv: This file logs statistics at regular intervals (defaulting to every 3 seconds). It’s great for seeing how your system’s performance changes over time during the test. You can plot this data to visualize trends.stats.csv: This file contains the final aggregated statistics for each request type at the end of the test. It gives you a snapshot of the overall performance.
Key Columns and What They Mean:
Both files share many common columns:
Method: The HTTP method (e.g., GET, POST).Name: The name of the request as defined in your Locustfile (e.g.,/users/{id},login).Request Count: The total number of times this request was made.Failure Count: The number of requests that resulted in an error.Median (ms): The median response time for this request type. This is often more representative than the average when you have outliers.Average (ms): The average response time.Min (ms): The minimum response time.Max (ms): The maximum response time.Average Content Length: The average size of the response body.# requests per second: The rate at which this request type was executed.
Let’s see it in action with a minimal Locustfile and its output:
First, here’s a simple locustfile.py:
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 2) # Wait 1-2 seconds between tasks
@task
def index(self):
self.client.get("/")
@task
def users(self):
self.client.get("/users")
@task
def post_user(self):
self.client.post("/users", json={"name": "test"})
Now, if you run this Locustfile (e.g., locust -f locustfile.py --headless -u 10 -r 10 --run-time 60s), after 60 seconds you’ll find stats.csv and stats_history.csv in your current directory.
Example stats.csv output:
Method,Name,Request Count,Failure Count,Median (ms),Average (ms),Min (ms),Max (ms),Average Content Length,# requests per second
GET,/,100,0,25.34,30.12,10.50,150.78,150,1.67
GET,/users,100,0,45.10,55.67,20.00,200.50,300,1.67
POST,/users,100,0,60.22,70.89,30.00,300.10,50,1.67
And stats_history.csv will show these metrics updating every 3 seconds. If your test was longer, you’d see rows like:
Timestamp,Method,Name,Request Count,Failure Count,Median (ms),Average (ms),Min (ms),Max (ms),Average Content Length,# requests per second
1678886400,GET,/,10,0,20.11,22.50,8.00,50.00,150,3.33
1678886403,GET,/,20,0,22.45,25.10,9.50,60.00,150,3.33
1678886400,GET,/users,10,0,40.50,43.00,18.00,90.00,300,3.33
1678886403,GET,/users,20,0,42.00,45.50,19.00,100.00,300,3.33
...
The stats_history.csv is where you can spot performance regressions. If you see the Median (ms) for /users steadily climbing from 45ms to 150ms over the test duration, you know something is degrading under load.
The true power comes when you combine this with the Locust failures.csv file, which logs every single failed request with its timestamp, method, URL, and the exception that occurred. This allows you to correlate performance degradation with specific errors or network issues.
When analyzing stats.csv or stats_history.csv, pay close attention to the Failure Count. If this number is non-zero, you must investigate the failures.csv file. A high Failure Count often indicates that your system is not handling the load, leading to timeouts or outright errors.
The Average Content Length can also be a subtle indicator. If it suddenly spikes for a particular request, it might mean your server is returning larger error pages or unexpected data under load, which can skew response times and consume more bandwidth.
The most surprising thing is how often people use stats.csv for trending when stats_history.csv is designed for precisely that. If you’re looking to understand how performance evolves during a test, plotting the Median (ms) or # requests per second from stats_history.csv over time is your go-to.
Understanding these CSVs is key to moving beyond simple "did it pass?" load testing to deep performance analysis.