Locust’s ramp-up and spike features let you simulate more realistic user load patterns than just a steady-state increase.

Here’s a Locustfile that models a complex load pattern with a ramp-up, a steady state, and then a sudden spike in user activity.

from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
    wait_time = between(1, 2) # Users wait 1-2 seconds between tasks

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

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

    def on_start(self):
        # This method is called when a user starts
        pass

    def on_stop(self):
        # This method is called when a user stops
        pass

To run this with a complex load pattern, you’d use Locust’s command-line interface. Let’s say you want to start with 10 users, ramp up to 100 users over 60 seconds, hold at 100 users for 5 minutes, and then spike to 300 users for 30 seconds before returning to 100 users.

Here’s how you’d construct the command:

locust -f your_locustfile.py --host=http://your-target-host.com --users 10 --spawn-rate 1 --run-time 10m --step-users 90 --step-time 60s --users 100 --spawn-rate 1 --step-users 200 --step-time 30s --users 100 --spawn-rate 1

Let’s break down that command:

  • locust -f your_locustfile.py: Standard command to run Locust with your specified file.
  • --host=http://your-target-host.com: The base URL of the application you are testing.
  • --users 10 --spawn-rate 1: This initiates the test with 10 users, spawning them at a rate of 1 per second. This is the baseline.
  • --step-users 90 --step-time 60s: This is the first step. After the initial setup, Locust will add 90 more users over 60 seconds. This brings the total to 100 users (10 initial + 90). The spawn-rate for this step implicitly uses the default or the one specified earlier.
  • --users 100 --spawn-rate 1 --run-time 5m: This part is crucial for defining the steady state. After the first step completes (reaching 100 users), Locust will ensure the user count stays at 100 for 5 minutes. The --spawn-rate 1 here ensures that if any users drop off, they are replaced to maintain 100, and --run-time 5m sets how long this phase lasts. Note: In practice, you might not need this explicit --users 100 again if the previous step naturally lands you there and you want to hold it. The --run-time argument can be used to specify the duration of a phase. A more direct way to express holding at 100 users for 5 minutes after the initial ramp is to simply let the previous step finish and then use --run-time for the total duration. However, for complex sequences, --step-users is the key.
  • --step-users 200 --step-time 30s: This is the spike. After the 5-minute steady state, Locust will add 200 more users over 30 seconds. This will temporarily bring the total user count to 300 (100 from the previous state + 200 new).
  • --users 100 --spawn-rate 1: After the spike, this command tells Locust to scale back down to 100 users. The system will gradually decrease users until it reaches 100.

The actual command structure for sequential steps is a bit more nuanced. Locust processes arguments sequentially. So, to achieve the described pattern:

  1. Initial state: Start with 10 users, spawning 1 per second.
  2. First Ramp-up: Add 90 users over 60 seconds.
  3. Hold Steady State: Maintain 100 users for 5 minutes.
  4. Spike: Add 200 users over 30 seconds.
  5. Scale Down: Return to 100 users.

A more precise way to express this sequence using Locust’s sequential_load feature (which is what the --step-users and --run-time flags effectively build upon in newer versions) would look more like this, specifying phases:

locust -f your_locustfile.py --host=http://your-target-host.com --stages \
    "10 users, spawn rate 1, 1m \
    then 100 users, spawn rate 10, 5m \
    then 300 users, spawn rate 50, 30s \
    then 100 users, spawn rate 10, 2m"

In this --stages example:

  • 10 users, spawn rate 1, 1m: Starts with 10 users, spawning at 1 user/sec for 1 minute.
  • then 100 users, spawn rate 10, 5m: After the first minute, ramps up to 100 users total, spawning at 10 users/sec, and holds this for 5 minutes.
  • then 300 users, spawn rate 50, 30s: After the 5 minutes, spikes to 300 users total, spawning at 50 users/sec, for 30 seconds.
  • then 100 users, spawn rate 10, 2m: After the spike, scales down to 100 users, spawning at 10 users/sec, and holds for 2 minutes (or until the total run time if specified).

The core idea is that Locust interprets these commands sequentially, adjusting the user count and spawn rate between phases. The --step-users flag in older versions or the --stages flag in newer versions are designed for this. The spawn-rate parameter is critical; it dictates how quickly Locust adds users during a ramp-up or to maintain a target user count. A higher spawn rate means a faster increase, potentially overwhelming the system more quickly during a spike.

The real power here is in simulating scenarios like:

  • Flash Sales: A sudden, massive influx of users.
  • End-of-Day Rushes: A sustained, high load for a period.
  • Background Processing Loads: A steady state with occasional bursts of user activity.

By precisely defining these phases, you can test how your application handles not just a constant load, but also the dynamic shifts that are common in real-world usage. The --stages syntax is generally preferred for its clarity in defining distinct phases of a test.

Want structured learning?

Take the full Locust course →