Gatling’s throttle clause lets you simulate realistic traffic patterns by precisely controlling the rate at which requests are injected into your system, not just the total number of requests.
Let’s see it in action with a simple scenario: simulating a spike in traffic followed by a gradual decrease.
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class RealisticTrafficSimulation extends Simulation {
val httpProtocol = http
.baseUrl("http://localhost:8080") // Replace with your target URL
.acceptHeader("application/json")
.contentTypeHeader("application/json")
val scn = scenario("Realistic Traffic")
.exec(http("Homepage")
.get("/"))
.pause(1) // Simulate user thinking time
.exec(http("Products Page")
.get("/products"))
.pause(2)
.exec(http("Product Detail")
.get("/products/123"))
// Define the throttling profile
setUp(
scn.inject(
// Ramp up to 100 requests per second over 30 seconds
rampUsersPerSec(0) to 100 during (30 seconds),
// Hold at 100 requests per second for 60 seconds
constantUsersPerSec(100) during (60 seconds),
// Gradually decrease to 20 requests per second over 30 seconds
rampUsersPerSec(100) to 20 during (30 seconds),
// Hold at 20 requests per second for 60 seconds
constantUsersPerSec(20) during (60 seconds)
)
).protocols(httpProtocol)
}
In this example, Gatling doesn’t just fire off a fixed number of requests. Instead, it meticulously manages the rate:
rampUsersPerSec(0) to 100 during (30 seconds): This starts with zero requests per second and smoothly increases the rate to 100 requests per second over the first 30 seconds. This simulates users gradually arriving and starting to interact with your application.constantUsersPerSec(100) during (60 seconds): For the next 60 seconds, Gatling maintains a steady rate of 100 requests per second. This is your peak load period.rampUsersPerSec(100) to 20 during (30 seconds): After the peak, the rate decreases from 100 down to 20 requests per second over 30 seconds. This simulates users starting to leave or their activity winding down.constantUsersPerSec(20) during (60 seconds): Finally, the system operates at a lower, sustained rate of 20 requests per second for the last 60 seconds.
The setUp block is where the magic happens. It takes a scenario (or multiple scenarios) and defines how users are injected over time using inject. Within inject, you use methods like rampUsersPerSec, constantUsersPerSec, atOnceUsers, or nothingFor to shape the traffic.
The core problem this solves is moving beyond simple "hit it with X users for Y minutes" tests. Real-world traffic isn’t a constant, uniform blast. It ebbs and flows, has peak hours, and can experience sudden bursts. throttle allows you to model these dynamic patterns, leading to more accurate performance insights. For instance, you can identify how your system behaves under a sudden surge of traffic (the ramp-up phase) or how it degrades gracefully (or not) as load decreases.
The key is understanding that UsersPerSec refers to the rate at which Gatling starts new virtual users. It’s not the number of concurrent users actively making requests at any given instant, though that’s a related metric you’ll see in the reports. Gatling manages the underlying ActorSystem to ensure it adheres to these specified rates, even if the actual requests take longer than the interval between them. If your requests are slow, Gatling will queue them up to maintain the target rate, which itself is a valuable indicator of system stress.
What most people miss is that rampUsersPerSec isn’t just about increasing load; it’s also about observing system behavior during the ramp. The initial ramp-up phase, where load is increasing, is often when latent issues or cascading failures first become apparent. Your system might handle a static 100 RPS fine, but struggle to transition to 100 RPS from 50 RPS if certain resources aren’t being released quickly enough.
The next logical step is to combine multiple throttling profiles to simulate even more complex, multi-phased traffic patterns, like daily usage cycles.