Throttle Request Rates in Gatling Load Tests
Learn how to shape the request rate of a Gatling test with the throttle injection profile, including setup, verification steps, and common recovery actions.
11 May 2026, 16:22 UTC

Desired outcome
You need a Gatling simulation that generates a controlled request rate—ramping up to a target, holding it, then ramping down—so you can observe system behavior under a known load pattern rather than relying solely on virtual‑user concurrency.
Necessary prerequisites
- Gatling 3.7+ installed and available on the PATH (the throttle DSL is present from 3.0).
- A Scala build tool (SBT or Maven) or the standalone Gatling bundle for quick runs.
- A simple HTTP endpoint to test, e.g. a mock service returning 200.
- Basic knowledge of Gatling scenarios:
exec,feed,http. - Permission to execute the Gatling launcher and read the simulation sources.
Focused procedure
- Create a scenario that performs the request you want to throttle. Example:
- Prepare a feeder or hard‑coded data if needed. For illustration a CSV feeder:
- Attach the feeder to the scenario:
- Define the throttle injection profile. The following example ramps to 50 requests/second over 10 seconds, holds for 30 seconds, then ramps down to 0 over 10 seconds:
- Place the simulation file under
src/test/scala(SBT) or any folder read by the standalone launcher. - Run the test:
- SBT:
sbt gatling:test - Standalone:
./gatling.sh -s com.example.ThrottledSimulation
val scn = scenario("Throttled API")
.exec(http("Get item"))
.get("/items/${itemId}")
.check(status.is(200))
val feeder = csv("itemIds.csv").circular
val scnWithFeed = scn.feed(feeder)
setUp(
scnWithFeed.inject(
nothingFor(5 seconds), // optional warm‑up
rampUsersPerSec(1) to 50 during(10 seconds),
constantUsersPerSec(50) during(30 seconds),
rampUsersPerSec(50) to 0 during(10 seconds)
).protocols(httpConf)
)
If you prefer the explicit throttle DSL, you can write:
setUp(
scnWithFeed.inject(
rampUsersPerSec(1) to 50 during(10 seconds)
).protocols(httpConf)
.throttle(
reachRps(50) in(10 seconds),
holdFor(30 seconds),
jumpToRps(0) in(10 seconds)
)
)
Expected checks
- Open the generated HTML report (
results//index.html). - In the “Requests per second” chart verify that the curve follows the ramp‑up, hold, and ramp‑down phases you defined.
- Check the “Global statistics” table: the total number of requests should be close to
target_rps × hold_time + area under ramp triangles(e.g. 50 × 30 + 0.5×50×10 + 0.5×50×10 = 2000 requests). - Ensure error rates are low; any spikes should be inspected against the target endpoint.
Recovery options
| Symptom | Likely cause | Recovery action |
|---|---|---|
| Requests per second stay flat at the initial value | The throttle block was omitted or the scenario was not attached to the injector | Confirm that .throttle(...) or the rampUsersPerSec chain is present and that the scenario passed to inject includes the feeder. |
| Observed rate exceeds the configured target | Multiple injection profiles were added without throttling each, or the protocol level maxConnections is too high |
Either apply throttle to every injector or consolidate them into a single throttled injection; review httpConf.maxConnectionsPerHost. |
| Test aborts with “java.lang.IllegalArgumentException: throttle must be positive” | A ramp target of zero or negative was supplied | Check the arguments to rampUsersPerSec or reachRps; ensure the final value is ≥ 0. |
| High error rates (5xx) during the hold phase | The target system cannot sustain the requested load | Lower the target RPS, increase ramp‑up/down times, or add think time (pause) inside the scenario. |
Version considerations
Gatling 3.0 introduced the throttle DSL; earlier 2.x versions required manual shaping with constantUsersPerSec and rampUsersPerSec only. If you are on Gatling 3.5 or later the nothingFor warm‑up step is available; otherwise omit it. Always verify your installation with gatling -version before copying the snippet.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.