Which keys does k6's `ramping-arrival-rate` executor take, and what does a stage `target` mean?
answer
- start value, then a list of stages
- no duration key on this one
- each stage carries target and duration
- target is a rate, not users
- startRate defaults to zero
basics
~20 sk6 v2's ramping-arrival-rate takes startRate, timeUnit and stages. Each stage is a target plus a duration, and the target is the arrival rate in iterations started per timeUnit that k6 ramps to linearly by the stage's end.
solid answer
~40 sIn k6 v2, `ramping-arrival-rate` is configured with `startRate` (defaults to `0`), `timeUnit` (defaults to `'1s'` and is fixed for the whole scenario), and `stages`, an array of `{ target, duration }` objects. A stage's `target` is a **rate** — iterations started per `timeUnit` — that k6 ramps to linearly from whatever rate the previous stage left off at, so a `target` equal to the current rate holds it flat. This executor has no `rate` key and no `duration` key; the scenario's length is the sum of its stage durations. Supplying `rate` or `duration` here is an unknown field, and k6 exits 104 before any iteration runs.
code
javascript · 22 linesimport http from 'k6/http';
export const options = {
scenarios: {
search_ramp_to_100: {
executor: 'ramping-arrival-rate',
startRate: 0,
timeUnit: '1s',
preAllocatedVUs: 50,
maxVUs: 300,
stages: [
{ target: 100, duration: '2m' },
{ target: 100, duration: '10m' },
{ target: 0, duration: '1m' },
],
},
},
};
export default function () {
http.get('https://example.com/search?q=laptop');
}go deeper
Recall that this executor is configured with startRate, timeUnit and a stages array, and that each stage is an object holding a target and a duration.
Explain that a stage target is an arrival rate in iterations per timeUnit, that k6 moves linearly from the previous rate to it, and that a target equal to the current rate is how you hold a plateau.
Show that you sanity-check a ramp shape before a long run: the scenario length is the sum of stage durations, there is no duration key to cap it, and a wrong key is a 104 exit rather than a silently different shape.
Consider whether a single ramp scenario is the right unit at all, or whether separate named scenarios with their own rates express the intent more legibly to the people who will read and re-run the script months later.
## The executor that moves the rate `ramping-arrival-rate` is the k6 v2 executor for load whose **arrival rate changes over the run**. Like `constant-arrival-rate` it schedules **iteration starts** — one iteration being a single top-to-bottom run of the scenario's `exec` function, the `default` export unless named otherwise — but instead of one fixed figure it walks the rate through a list of stages. Its keys are `startRate`, `timeUnit` and `stages`, plus the pool keys `preAllocatedVUs` (required) and `maxVUs`. It has **no `rate` key and no `duration` key**; those two belong to `constant-arrival-rate`. That distinction is the single most common configuration mistake on this executor, because every token involved is a real k6 identifier, so a merged list looks plausible while being wrong. | key | on `constant-arrival-rate` | on `ramping-arrival-rate` | |---|---|---| | `rate` | required, integer | not a key | | `startRate` | not a key | optional, defaults to `0` | | `timeUnit` | optional, defaults to `'1s'` | optional, defaults to `'1s'` | | `duration` | required | not a key | | `stages` | not a key | required, array of `{ target, duration }` | ## What a stage `target` means Each entry of `stages` is an object with two fields: - **`duration`** — how long the stage lasts. There is no separate scenario `duration`; the scenario's length is the sum of its stages' durations. - **`target`** — the arrival rate k6 should be at **when the stage ends**, expressed in iterations started per `timeUnit`. `target` is a **rate**, not a count of iterations and not a count of virtual users. This is where the executor most often surprises people, because the identically named `target` field inside `ramping-vus` stages *is* a VU count. In `ramping-arrival-rate` it is a rate, and the `timeUnit` that gives it meaning is fixed for the whole scenario — you cannot vary `timeUnit` per stage. Between one stage's starting rate and its `target`, k6 ramps **linearly**. Consequences worth holding on to: - A stage whose `target` equals the rate it begins at is a **hold**, not a no-op — it keeps the rate flat for its `duration`. - A stage whose `target` is lower than the current rate is a **ramp down**; targets may fall as well as rise. - A `target` of `0` drives the arrival rate to zero, so no new iterations are started at the end of that stage. - The first stage ramps from `startRate`, which **defaults to `0`** — omit `startRate` and your run begins from a standstill. ## Walking a search-endpoint ramp Take a search endpoint that should climb to a flat 100 requests per second, hold there, and come back down. In k6 v2 that is three stages: 1. `{ target: 100, duration: '2m' }` — starting from `startRate: 0`, the rate rises linearly from 0 to 100 iterations per second over two minutes. 2. `{ target: 100, duration: '10m' }` — the target equals the rate already reached, so the scenario holds a flat 100 per second for ten minutes. 3. `{ target: 0, duration: '1m' }` — the rate falls linearly back to zero over the final minute. The whole scenario therefore lasts thirteen minutes, and k6's progress line describes it as *up to 100.00 iterations/s ... over 3 stages*. As with the flat executor, 100 iterations per second equals 100 requests per second only if one iteration issues exactly one request. ## Why a merged key list fails hard k6 parses each scenario block strictly against the executor you named: a key that executor does not define is an **unknown field**, and the configuration as a whole is refused. So each of these is a pre-run failure, not a warning: - `duration` on a `ramping-arrival-rate` scenario — unknown field. - `rate` on a `ramping-arrival-rate` scenario — unknown field. - `stages` or `startRate` on a `constant-arrival-rate` scenario — unknown field. - `ramping-arrival-rate` with no `stages` at all — validation reports *"at least one stage has to be specified"*. - A stage missing its `target` or `duration` — validation reports which stage number is at fault. In every case the process exits **104** (`InvalidConfig`) before a single iteration runs. That is the good outcome: the alternative would be a thirteen-minute run that quietly applied a shape you did not write. When a ramp scenario refuses to start, read the message for a key name and check it against the executor's own list rather than against the other one.
- How long does a k6 ramping-arrival-rate scenario run, given it has no duration key?For the sum of its stage durations. Stages of `2m`, `10m` and `1m` give a thirteen-minute scenario. Adding a `duration` key to shorten or extend that does not work — the executor does not define one, so k6 refuses the configuration and exits 104.
- In a k6 ramping-arrival-rate scenario, what does a stage whose target equals the previous rate do?It holds the rate flat for that stage's `duration`. k6 ramps linearly from the rate in force to the stage's `target`; when the two are equal the line is horizontal, which is how you express a steady plateau between a ramp up and a ramp down.
- Can timeUnit differ from stage to stage in a k6 ramping-arrival-rate scenario?No. `timeUnit` is a single scenario-level key and its value is constant for the whole scenario; every stage `target` is read against the same unit. To change the unit you need a separate scenario in the `scenarios` map.
saying these in an interview costs you the question
- Reads a stage target as a VU count, as in ramping-vus
- Gives ramping-arrival-rate a duration key that it does not define
- Adds rate alongside stages on the ramping executor
- Thinks a stage target is the total iterations run in that stage
- Assumes startRate is required rather than defaulting to zero
- Believes timeUnit can be set per stage