You can run a distributed load test with Locust in under 5 minutes, and the most surprising thing is how little infrastructure you actually need to get started.

Let’s fire up a simple load test. First, we need a locustfile.py to define our test behavior.

from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
    wait_time = between(1, 5)

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

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

This locustfile.py defines a user that will make GET requests to the root / and /about/ paths of a web application. The wait_time = between(1, 5) means each user will wait between 1 and 5 seconds between tasks.

Now, install Locust itself.

pip install locust

Once installed, you can start a single-node Locust instance from your terminal. We’ll point it to a target website using the --host flag. For this example, let’s use http://example.com.

locust -f locustfile.py --host http://example.com

This command starts Locust in the foreground. It will print some output indicating it’s running and ready to accept connections. Open your web browser and navigate to http://localhost:8089. You’ll see the Locust web UI.

In the web UI, you’ll see two input fields: "Number of users" and "Spawn rate". Let’s set "Number of users" to 100 and "Spawn rate" to 10. Click "Start swarming".

Locust will now start spawning 100 users, with 10 users starting every second. These users will begin executing the tasks defined in your locustfile.py against http://example.com. The web UI will update in real-time, showing you metrics like the number of requests per second, response times, and failure rates. You can see the distribution of response times and identify any bottlenecks in the target application.

This setup is incredibly powerful because Locust is designed for distributed execution. While we ran a single node locally, you can scale this out. You’d typically run one "master" node and multiple "worker" nodes. The master coordinates the test, and the workers actually generate the load.

To run in distributed mode, you’d start a master like this:

locust -f locustfile.py --host http://example.com --master

And then on separate machines (or even separate terminal windows on the same machine for testing), you’d start worker nodes, pointing them to the master:

locust -f locustfile.py --host http://example.com --worker --master-host <master_ip_address>

The master node’s web UI (still at http://localhost:8089 if you’re running the master locally) will aggregate the results from all workers. This allows you to simulate thousands or even millions of concurrent users by simply adding more worker machines. The "spawn rate" in the UI then becomes the total spawn rate across all workers.

The core problem Locust solves is simulating realistic user behavior at scale, allowing you to test the performance and stability of your applications under heavy load without needing to provision and manage complex testing infrastructure yourself. It’s pure Python, so if you know Python, you can write sophisticated load tests.

The default behavior of Locust is to run tasks sequentially within a user. If you have multiple tasks defined in a User class, Locust will pick one and execute it, then wait for wait_time, then pick another, and so on. However, if you need to execute tasks concurrently within a single user, you would use the sequential=False argument when defining tasks, or more commonly, group tasks into TaskSets and use self.schedule_task or self.schedule_next_task for more complex flow control, allowing a single user to perform multiple actions in parallel or in a specific, non-sequential order, before waiting.

The next step is to explore how to simulate more complex user journeys and handle dynamic data.

Want structured learning?

Take the full Locust course →