skip to content

Your Gatling run must sit at 200 requests per second across two scenarios, so how would you decide between declaring that rate with throttle and declaring it in the injection profile?

level: principalimportance: should knowfreq 30%

answer

  1. Requirement or guard rail, decide first
  2. Profile keeps pauses and mix
  3. Throttle buys a total, costs shape
  4. A generator property, not a system one

basics

~20 s

Decide by what the number is. A rate the test exists to prove belongs in the injection profile, which keeps think time and the request mix intact. A rate that is only a safety limit belongs in throttle.

solid answer

~50 s

Ask whether 200 is a requirement or a guard rail. If the run exists to prove the system sustains 200 requests per second, put the rate in the injection profile — Gatling's own documentation recommends an open-model step such as `constantUsersPerSec` for exactly this — because the profile preserves the scenario's pauses, keeps the request mix as written, charts directly in the report and covers every protocol. Reach for `throttle(...)` when the number is a cap you must not exceed: a shared environment, a contractual limit, a single-request scenario. Then price what it costs. A throttle forces the pause policy off — only a pause given an explicit pause type still waits — gives no control over which requests fill the ceiling, parks everything above it in an unbounded injector buffer, bounds the run's duration by its own length, and applies to HTTP and JMS only.

code

java · 9 lines
java
setUp(
  browse.injectOpen(constantUsersPerSec(120).during(Duration.ofMinutes(10))),
  checkout.injectOpen(constantUsersPerSec(80).during(Duration.ofMinutes(10)))
).protocols(httpProtocol)
 .maxDuration(Duration.ofMinutes(11))
 .throttle(
   reachRps(220).in(Duration.ofSeconds(30)),
   holdFor(Duration.ofMinutes(10))
 );

go deeper

for a junior

Be ready to say that a rate can be declared either in the injection profile or as a throttle ceiling, and that the profile is the usual place.

for a middle

Be ready to list what a throttle changes beyond the rate: the pause policy off unless a pause carries its own type, request mix unguaranteed, excess buffered, run duration bounded, HTTP and JMS only.

for a senior

Be ready to choose per run and defend it, and to say which figures in a throttled run's report you would still trust.

for a principal

Be ready to set the team-wide rule, including that throttled and unthrottled results are never compared and that a ceiling is never reported as capacity.

Gatling gives you two ways to make a run sit at 200 requests per second across two scenarios, and they are not equivalent. One expresses the rate as **demand**, in the injection profile; the other expresses it as a **limit**, with `throttle(...)`. Choosing well means knowing which guarantee you are actually buying. ## The two candidates ```java // demand: the profile produces the rate setUp( browse.injectOpen(constantUsersPerSec(120).during(Duration.ofMinutes(10))), checkout.injectOpen(constantUsersPerSec(80).during(Duration.ofMinutes(10))) ).protocols(httpProtocol); // limit: the profile produces more, the ceiling trims it setUp( browse.injectOpen(constantUsersPerSec(200).during(Duration.ofMinutes(10))), checkout.injectOpen(constantUsersPerSec(200).during(Duration.ofMinutes(10))) ).protocols(httpProtocol) .throttle(reachRps(200).in(Duration.ofSeconds(30)), holdFor(Duration.ofMinutes(9))); ``` Gatling's own documentation is not neutral between them. It says that if your virtual users perform only one request each you *should* use an open-model injection step such as `constantUsersPerSec`, and that a throttle over a multi-request scenario will leave you without *"any means of controlling which request gets executed"*. ## What each side actually costs | dimension | rate in the injection profile | rate via `throttle(...)` | |---|---|---| | think time | preserved as declared | deleted, unless a pause forces its own pause type | | which requests make up the rate | follows the scenario as written | whichever request asks first | | excess traffic | none: the profile produces the rate | parked in an unbounded injector buffer | | run duration | bounded by the profile or `maxDuration` | also bounded by the throttle profile's length | | protocols covered | all of them | HTTP and JMS only | | fractional rates | yes | no — the target is an integer | Read that table as one sentence: a throttle buys a hard total and pays for it with the shape of the traffic underneath. ## The questions worth asking before you decide 1. **Is the number a requirement or a safety limit?** If the test exists to prove the system handles 200 requests per second, the rate is the *subject* of the test and belongs in the profile, where the report's arrival-rate chart will show it. If the number exists to stop a shared environment being flattened, it is a limit, and a throttle is the right shape. 2. **Does the mix matter?** A scenario that issues several different requests gets no guarantee about which of them fill the ceiling. If the ratio of reads to writes is part of what you are testing, a throttle will not preserve it and per-population throttles only move the problem down one level. 3. **Do the pauses matter?** A throttle deletes every pause that takes the population's pause policy; only a pause given an explicit pause type, such as `pause(Duration.ofSeconds(5), constantPauses)`, survives it. If the scenario's think time is part of the workload you agreed with the product team, throttling changes the workload, not just its ceiling. 4. **How far above the ceiling will the profile run?** The gap is parked in the load generator's heap with no bound. A ceiling near the offered traffic is cheap; a ceiling an order of magnitude below it is a memory failure waiting to happen. 5. **Is every protocol in the scenario covered?** Throttling reaches HTTP requests and JMS. A scenario that also opens WebSockets will exceed the ceiling on that traffic silently. ## A defensible default For most teams the rule that holds up is: **express the rate you want in the injection profile, and reserve `throttle(...)` for a guard rail.** The profile is the declaration a reviewer can read, the report charts it directly, and nothing about the scenario is silently rewritten. A throttle then earns its place only in the narrow cases it was built for — a single-request scenario, a shared environment with a contractual cap, or a run where an accidental overshoot would be expensive. Where a throttle is allowed, write the rule down as three constraints rather than as a permission: * The ceiling must be within a small factor of what the injection profile offers. * Every population's throttle profile must be the same total length, since the shortest one becomes the run's clock. * Results from throttled runs are not compared against results from unthrottled ones, because the pause policy differs between them. ## What you should not claim for it A throttle is a property of the **load generator**, not of the system under test. It says what Gatling will send; it says nothing about what the target can absorb, and it is not a substitute for whatever limiting the service itself does. Keeping that distinction crisp is most of the judgement this decision needs.

  • A team wants a throttle on every simulation so no run can ever flatten the shared environment. What do you push back on?
    That it rewrites every scenario. A throttle forces the pause policy off, so every run's think time disappears unless each pause carries its own pause type, and no result stays comparable with the archive. Set the ceiling generously above the intended rate so it only catches an overshoot, and require that throttled and unthrottled results are never compared.
  • Which part of a throttled run's report should you distrust?
    The shape rather than the total. The ceiling is honoured, but the split between the scenario's different requests is whatever arrival order produced, the think time is gone unless each pause forced its own pause type, and time a request spent parked before it was issued is not in its response time. The total requests per second is the one figure the throttle actually guarantees.
  • Does a Gatling throttle tell you anything about the system under test?
    No. It is a property of the load generator alone: it describes what Gatling will send, not what the target can absorb, and it is unrelated to whatever limiting the service itself applies. Treating a throttle ceiling as a measured capacity figure is a category error.

saying these in an interview costs you the question

  • Using a throttle to express the workload the test is about
  • Mandating throttles suite-wide and silently deleting the scenarios' think time
  • Setting a ceiling far below the traffic the profile offers
  • Reading a throttle ceiling as the system's measured capacity