skip to content

Rate Bound

The two k6 executors that start iterations on a schedule whatever the system is doing, so a slowdown surfaces as dropped work instead of a quietly lower rate. Asked because that is the honest shape.

on this pageshow

explore

questions

9

In a k6 `constant-arrival-rate` scenario, what do the `rate`, `timeUnit` and `duration` keys each set?

level: juniorimportance: must knowfreq 74%

answer

  1. three keys, one flat schedule
  2. count, period, and how long
  3. the period the rate applies to
  4. timeUnit defaults to one second
  5. rate counts iteration starts

basics

~10 s

In k6 v2, rate is how many iterations the executor starts during each timeUnit period, timeUnit is that period (default 1s), and duration is how long the scenario keeps starting them.

solid answer

~40 s

In k6 v2, `constant-arrival-rate` describes a flat schedule of iteration starts with three keys. `rate` is an integer count of iterations to start during each period; `timeUnit` is that period and defaults to `'1s'`; `duration` is how long the scenario keeps issuing starts, and it excludes the `gracefulStop` window that follows. So `rate: 100, timeUnit: '1s', duration: '10m'` starts 100 iterations every second for ten minutes. `rate` counts iteration starts, not virtual users and not HTTP requests — a flat 100 requests/s at a search endpoint only follows if one iteration issues exactly one request. `rate` and `duration` are required; k6 exits 104 if either is missing.

code

javascript · 18 lines
javascript
import http from 'k6/http';

export const options = {
  scenarios: {
    search_flat_100: {
      executor: 'constant-arrival-rate',
      rate: 100,
      timeUnit: '1s',
      duration: '10m',
      preAllocatedVUs: 50,
      maxVUs: 200,
    },
  },
};

export default function () {
  http.get('https://example.com/search?q=laptop');
}

go deeper

for a junior

Recall the three keys and say what each one holds: rate is a count of iteration starts, timeUnit is the period that count applies to and defaults to 1s, and duration is how long the scenario keeps starting them.

for a middle

Explain that rate and timeUnit are read as one ratio, so rate 100 per 1s and rate 6000 per 1m are the same schedule, and that rate counts iteration starts rather than requests or users.

for a senior

Show that you check the required keys before a long run, since a missing rate or duration costs a 104 exit rather than a partial result, and that you make one iteration equal one request when the brief is stated in requests per second.

for a principal

Weigh whether the load target should be declared as an arrival rate at all, and who owns the number: a rate written into the scenario block is a contract the team reads, so keep it in one place rather than scattered across environment overrides.

## What `constant-arrival-rate` schedules `constant-arrival-rate` is one of the six executors k6 v2 ships — the others are `shared-iterations`, `per-vu-iterations`, `constant-vus`, `ramping-vus` and `ramping-arrival-rate`. You select it inside the `scenarios` map of the exported `options` object by putting `executor: 'constant-arrival-rate'` on a named scenario. What it schedules is **iteration starts**: k6 plans a fixed number of starts per unit of time and launches each one at its planned instant, for as long as you tell it to. An **iteration** here is one top-to-bottom run of the scenario's `exec` function, which is the script's `default` export unless the scenario names a different one. Exactly three keys describe that schedule, and between them they are the whole of it: `rate`, `timeUnit` and `duration`. ## The three keys, one at a time | key | type | required | default | what it sets | |---|---|---|---|---| | `rate` | integer | yes | — | how many iterations k6 starts during each `timeUnit` | | `timeUnit` | duration string | no | `'1s'` | the period the `rate` count is measured over | | `duration` | duration string | yes | — | how long the scenario keeps starting iterations | - **`rate`** is an integer count of starts, not a fraction. The figure is fixed for the whole scenario: `constant-arrival-rate` defines no key that alters it part-way through, which is precisely the job `ramping-arrival-rate` exists to do. - **`timeUnit`** is only the denominator you choose to write the rate in. k6 reduces `rate / timeUnit` to one arrival rate before scheduling anything, so `rate: 100` with `timeUnit: '1s'` and `rate: 6000` with `timeUnit: '1m'` describe the identical schedule. Its practical use is expressing rates the integer `rate` cannot: one iteration every ten seconds is `rate: 1, timeUnit: '10s'`. - **`duration`** bounds the window during which new starts are issued; it does not include the `gracefulStop` period that follows, during which already-running iterations may finish. It has a floor of one second — k6 reports *"the duration must be at least 1s"* below that. Two further keys, `preAllocatedVUs` (required) and `maxVUs`, tell k6 how large a pool of virtual users it may draw on to serve that schedule. They size the pool that executes the plan; they do not shape the plan, and sizing them is a separate subject from the three keys above. ## Reading a flat 100/s search scenario Suppose the brief is *hold a search endpoint at a flat 100 requests per second for ten minutes*. In k6 v2 that reads out as four decisions: 1. Pick the executor. The rate never changes across the run, so it is `executor: 'constant-arrival-rate'`; `ramping-arrival-rate` is the one whose rate moves. 2. Set `rate: 100` and `timeUnit: '1s'`. Read together they say *start 100 iterations every second*. `timeUnit` could be omitted here, since `'1s'` is its default, but writing it makes the pair self-documenting. 3. Set `duration: '10m'`. After ten minutes k6 stops issuing new starts. 4. Write the `default` function so one iteration issues exactly one request to the search endpoint. Only under that condition does *100 iterations per second* coincide with the *100 requests per second* the brief asked for. While the run is live, k6's description of the scenario opens with the figure it derived from your keys — `100.00 iterations/s for 10m0s` — which is the quickest way to confirm the two keys were read the way you meant them. ## What these three keys do not do - `rate` does **not** set a number of virtual users. It counts starts; how many VUs k6 needs to serve them follows from how long an iteration takes. - `rate` does **not** count HTTP requests. An iteration that issues three requests turns `rate: 100` into roughly 300 requests per second at the endpoint. - `timeUnit` is **not** a batching window. k6 does not release `rate` iterations together at each period boundary; it spaces the starts fractionally across the period. - There is no `stages` key and no `startRate` key on this executor. Both belong to `ramping-arrival-rate`, and k6 will not accept either one here. - Omitting `duration` does not mean *run until interrupted*. It is a missing required option. ## How k6 rejects a bad configuration k6 parses each scenario strictly: any key the selected executor does not define is an unknown field and the whole configuration is refused. Validation then checks the values that were accepted. In k6 v2 both failures surface identically — no iteration runs and the process exits **104** (`InvalidConfig`) — and the messages name the key: - `rate` missing: *"the iteration rate isn't specified"*. - `rate` zero or negative: *"the iteration rate must be more than 0"*. - `duration` missing: *"the duration is unspecified"*. - `timeUnit` zero or negative: *"the timeUnit must be more than 0"*. Because all of this happens before the first iteration, a typo in one of the three keys costs a failed start rather than a wasted ten-minute run. When a scenario refuses to launch, the exit code tells you which kind of problem you have: 104 is your configuration, and any other code is something else entirely.

  • How would you configure a k6 constant-arrival-rate scenario to start one iteration every ten seconds?
    `rate` is an integer, so put the fraction into `timeUnit`: `rate: 1, timeUnit: '10s'`. `rate: 6, timeUnit: '1m'` gives the same schedule, because k6 reduces `rate / timeUnit` to a single arrival rate before it plans anything.
  • What is the shortest duration a k6 constant-arrival-rate scenario accepts?
    One second. Anything below that is rejected during validation with *"the duration must be at least 1s"*, and k6 exits 104 without running an iteration. The same one-second floor applies to `constant-vus`.
  • Does adding a stages array to a k6 constant-arrival-rate scenario make the rate ramp?
    No. `stages` is not a key this executor defines, so k6 treats it as an unknown field, refuses the whole configuration and exits 104. A moving rate needs `ramping-arrival-rate`, which takes `startRate` and `stages` instead of `rate` and `duration`.

saying these in an interview costs you the question

  • Thinks rate sets the number of VUs the scenario runs
  • Reads rate as requests per second whatever the iteration does
  • Believes timeUnit must be seconds and cannot be 1m
  • Adds a stages array to constant-arrival-rate, which has no such key
  • Assumes omitting duration lets the scenario run until interrupted
  • Treats timeUnit as a batch window that releases rate iterations at once
open as a page

In a k6 arrival-rate scenario, what do preAllocatedVUs and maxVUs control, and what happens when maxVUs is omitted?

level: juniorimportance: must knowfreq 74%

basics

~10 s

preAllocatedVUs is the number of VUs k6 initializes before an arrival-rate scenario starts; maxVUs is the hard ceiling that pool may grow to mid-run. Omitted, maxVUs equals preAllocatedVUs, so the pool never grows.

open as a page

Which keys does k6's `ramping-arrival-rate` executor take, and what does a stage `target` mean?

level: middleimportance: must knowfreq 66%

basics

~20 s

k6 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.

open as a page

When a k6 arrival-rate scenario has no free VU at an iteration's scheduled start, what does k6 do?

level: middleimportance: must knowfreq 68%

basics

~20 s

An arrival-rate start that finds no free VU is abandoned and counted on k6's built-in dropped_iterations counter. If maxVUs headroom remains k6 begins building one more VU in the background; at the ceiling it logs an Insufficient VUs warning.

open as a page

In a k6 `constant-arrival-rate` scenario with `rate: 100` and `timeUnit: '1s'`, when does each iteration start?

level: middleimportance: should knowfreq 48%

basics

~20 s

k6 spaces arrival-rate starts fractionally, not in a burst: it turns rate over timeUnit into one interval, so 100 per second plans a start roughly every 10 ms at fixed offsets from the scenario's start.

open as a page

How do you pick preAllocatedVUs for a k6 constant-arrival-rate scenario targeting 500 iterations per second?

level: middleimportance: should knowfreq 61%

basics

~20 s

Use k6's rule of thumb: preAllocatedVUs is roughly the median iteration duration times the rate, plus headroom. At 500 iterations per second with a 200 ms iteration that is about 100 VUs; then tune until dropped_iterations stays at zero.

open as a page

Your k6 `constant-arrival-rate` scenario sets `rate: 100` but the search endpoint sees 300 requests/s. Why?

level: seniorimportance: should knowfreq 41%

basics

~10 s

k6's rate counts iteration starts, not HTTP requests. Each start runs the whole exec function, so an iteration issuing three calls turns rate 100 into about 300 requests per second at the endpoint.

open as a page

A k6 ramping-arrival-rate run records many dropped_iterations but never logs an Insufficient VUs warning. Why?

level: seniorimportance: should knowfreq 52%

basics

~20 s

k6 logs the Insufficient VUs warning only once its maxVUs growth budget is exhausted, so its absence means the pool never reached maxVUs. Every start finding no free VU is still dropped while the pool grows.

open as a page

When is setting maxVUs above preAllocatedVUs in a k6 arrival-rate scenario worth its cost?

level: principalimportance: should knowfreq 43%

basics

~20 s

Rarely - k6 builds each VU above preAllocatedVUs mid-run by re-running the init context on the machine already generating load, and in Grafana Cloud maxVUs is what counts against the subscription. Reserve it for first-time sizing.

open as a page