Locust is an open source load-testing tool written in Python. It lets you write tests against your web application which mimic your user’s behavior, and then run the tests at scale to help find bottlenecks or other performance issues. At Promptworks, we use it regularly to make sure that the web applications we write are able to handle a high load and remain performant.

Installation

Installation is done with Python’s pip :

$ pip install locustio

Configuration

One of the nicest features of Locust is that configuration is done via "Plain Old Python." You simply create a file named locustfile.py and all configuration for your load tester and its tests is done there.

Here's an example locustfile.py , which defines a simple user behavior which consists of a single "task" which gets a specific webpage:

from locust import HttpLocust, TaskSet, task class UserBehavior(TaskSet): @task def get_something(self): self.client.get("/something") class WebsiteUser(HttpLocust): task_set = UserBehavior

We can add a second task as follows:

class UserBehavior(TaskSet): @task def get_something(self): self.client.get("/something") @task def get_something_else(self): self.client.get("/something-else")

When the above UserBehavior is run, Locust will randomly choose between each of the tasks and run them. If you want to weight different tasks differently, so that one is run twice as much as the other, you can add weighting as follows:

class UserBehavior(TaskSet): @task(2) def get_something(self): self.client.get("/something") @task(1) def get_something_else(self): self.client.get("/something-else")

These task weights are ratios across all defined tasks, so here get_something would happen twice as often during the load test.

You can also write tasks which compose other tasks, to perform a sequential or serial set of tasks in a specific order. This lets you define a user flow through multiple requests. For example:^1

class UserBehavior(TaskSet): @task def get_something(self): self.client.get("/something") @task def get_something_else(self): self.client.get("/something-else") @task def get_two_things(self): self.get_something() self.get_something_else()

A TaskSet class can optionally declare an on_start function, which is called when a simulated user starts executing that TaskSet class. This can be used to log in or apply credentials once before beginning the load test:

class UserBehavior(TaskSet): def on_start(self): self.client.post("/login", { 'username': 'foo', 'password': 'bar' }) @task def get_something(self): self.client.get("/something")

Running Locally

To run Locust, you run the locust command in the same directory as your locustfile.py :

$ locust --host=http://localhost:5000

Once the command is run, Locust starts up a local web server which you can visit in your browser: