Your Gatling run must take a service from 300 concurrent users down to 50 at the end — would you express that as a ramp step, a step change, or by ending the population, and how would you decide?
answer
- Decay is the slower of completion rate and declared slope
- No wind-down form interrupts a running user
- Decide by what the lower level is for
- Window sized in scenario iterations, not seconds
- A wind-down nobody reads is wasted run time
basics
~30 sNone of the three interrupts a running user, but they do not come down at the same speed. A ramp keeps replacing finished users against its falling target, so the population follows the declared slope; a step change and the end of the population both shed load at the full completion rate. Ramp when the descent itself is measured or must be gentle; step down when only the lower level matters; end the population when neither is read.
solid answer
~60 sAll three are legal closed-model profiles, and none of them interrupts a running user — but a lower target does not merely stop replacement. Gatling compares concurrency against the target *for the current second*, which during a ramp is an interpolated value on the falling line, so a ramp keeps replacing finished users and holds the population on its declared slope, while a step change — or the end of the profile — drops the target in one move and lets the population fall at the full completion rate. The measured decay is the slower of the two, min(completion rate, declared slope), and the three shapes coincide only when one scenario iteration is long relative to the window. So decide by what 50 is *for*, and say which of those two regimes the suite is in. If 50 is a measurement window, you need a held `constantConcurrentUsers(50)` step long enough to settle. If it is a recovery observation, the ramp earns its place — it genuinely spends run time coming down gently — and must be at least one scenario iteration long. If nothing asserts on it, end the population and save the run time.
go deeper
Be ready to name the three shapes a wind-down can take in a closed profile and to write each one as injection steps.
Be ready to explain why a ramp holds the population on its declared line while a step change and the end of the population shed load at the full completion rate, and when the two converge.
Be ready to size a wind-down window from a measured scenario iteration and to justify the run time it costs on every build.
Be ready to own the policy: whether wind-downs are part of the pass criteria at all, the minimum window rule expressed in iterations, and the wall-clock budget the suite runs inside.
## Three ways to write the same intent Ending a run at a lower level than it held is a shape you can express three ways in Gatling's closed injection DSL, and all three are legal: 1. **A ramp step** — `rampConcurrentUsers(300).to(50).during(d)`, followed by `constantConcurrentUsers(50).during(d)` if 50 must then be held. 2. **A step change** — `constantConcurrentUsers(300).during(d)` followed immediately by `constantConcurrentUsers(50).during(d)`, with no ramp between them. 3. **Ending the population** — stop after the hold and let the run drain. ## How fast load actually falls Here is the thing that surprises people twice over. First: **none of the three removes a running virtual user** — only completing the scenario does that. Second, and far less often understood: a lower target does **not** merely stop replacement. Gatling compares the population against the target for the *current second*, which during a ramp is an interpolated value on the falling line. So a ramp keeps replacing finished users all the way down and holds the population on its declared slope, while a step change — or the end of the population — drops the target in one move and lets the population fall at the full completion rate. The measured decay is therefore the **slower of the two**: `min(completion rate, declared slope)`. Worked through: taking 300 concurrent users to 50 over 30 seconds drops the target by about 8.3 users a second, and the same move over 30 minutes drops it by about 0.14. If one scenario iteration takes ten seconds, the 300 users in flight complete at roughly 30 a second — comfortably faster than the steep line — so the population follows that line down and ends the half-minute close to 50. It would follow the shallow line just as faithfully, which is the point: ten minutes into *that* version the population is still around 215. Same intent, two very different runs. The shapes only coincide when one scenario iteration is long relative to the wind-down window, because then completion is the binding constraint whatever you declared. Below that, the ramp is the *slow* option, deliberately: it is a genuine choice to spend run time coming down gently, not merely a different line on the chart. That sharpens the decision rather than dissolving it. You are choosing a wind-down speed **and** what the report will say, and the first thing to establish is which of the two regimes the suite is in, measured against one scenario iteration. ## What each option buys | option | what it gives you | what it costs | |---|---|---| | ramp to 50, then hold 50 | a controlled descent the population actually follows, plus a clean steady window at the lower level | the longest run; the ramp is meaningless if shorter than one iteration | | step straight to 50 | the fastest descent available — the full completion rate — and the simplest profile to read | the measured curve lags the cliff by up to an iteration and the transition is unattributable | | end the population | shortest run; nothing to explain | no measurement at 50 at all, and the drain still costs one iteration | ## How to decide Ask what the lower level is *for*: - **If 50 is a measurement**, and you intend to compare it against the 300 hold, you need a held step at 50 long enough to produce a steady window — and you need the transition out of the way before that window starts. A step change gets there fastest, because nothing is replaced on the way down; a ramp costs its own length but arrives with the chart showing an intended transition rather than a cliff the reader has to explain. - **If 50 is only a recovery observation** — you want to see the service settle after the load comes off — then the shape of the transition is the subject, and the ramp earns its place. Make the ramp at least as long as one scenario iteration or the measured curve will never track it. - **If 50 is neither**, and the run's conclusion comes entirely from the 300 hold, end the population. A wind-down you will not read is run time you are paying for on every build. ## The constraint that decides the window Whatever you choose, one measurement governs it: **how long a single scenario iteration takes**. It is the ceiling on how fast any of the three shapes can shed load, and so it sets the floor on any wind-down window, the length of the drain at the end of the run, and how long after a step change the measured level takes to arrive. Measure it before you pick the numbers, and re-measure it when the scenario changes — a wind-down window that tracked last quarter will quietly stop tracking when someone adds a step to the journey. ## What to agree with the team - **Whether a wind-down is part of the pass criteria at all.** If nothing asserts on it, it is optional, and the honest thing is to say so rather than keep it out of habit. - **A minimum window rule**, expressed in iterations rather than seconds, so it survives changes to the scenario. - **A wall-clock budget** for the whole run, bounded by `maxDuration` on `setUp`, because the drain after the last step is unbounded by default. ## Common mistakes - Choosing a ramp "to bring load down gently" without measuring the iteration first. It really does control the descent — but only while its slope is shallower than the rate scenarios complete; steeper than that, completion is doing all the work and the ramp is just a prettier line. - Declaring a thirty-second wind-down for a scenario whose iteration is two minutes. - Comparing the 300 window and the 50 window without checking that the measured level had actually settled at 50 before the second window started. - Leaving a wind-down in every profile that nobody reads, and paying for it on every pipeline run.
- What would make you skip the wind-down entirely and end the population at 300?When the run's conclusion comes wholly from the 300 hold and nothing asserts on the lower level. You pay one scenario iteration of drain either way, so the wind-down adds only run time and a chart segment nobody reads. Say so explicitly rather than keeping it out of habit.
- How long must a wind-down window be for the measured curve to follow it?At least one full scenario iteration, and comfortably more if you want the curve to track rather than merely catch up at the end. Express the rule in iterations rather than seconds, so it survives someone adding a step to the journey.
- Does a steeper declared ramp make load come off faster?Yes, up to a ceiling. The declared slope is the target the injector replaces finished users against, so a steeper ramp does shed load faster — until the slope exceeds the rate at which scenarios complete, at which point completion becomes the binding constraint and steepening buys nothing. Below that ceiling the slope is the lever; above it, the only levers left are a shorter scenario iteration and a longer window.
saying these in an interview costs you the question
- Choosing a ramp for a gentle descent without checking its slope against the completion rate.
- Declaring a thirty-second wind-down for a two-minute scenario iteration.
- Comparing two windows before the measured level had settled.
- Keeping a wind-down in every profile that nobody ever reads.