skip to content

Exported Options Object

A k6 test has no separate configuration format: the exported options object is the configuration, evaluated at init. Interviewers ask because it puts load settings under version control.

on this pageshow

explore

questions

5

In k6, what is the exported `options` object and how does it configure a test run?

level: juniorimportance: must knowfreq 82%

answer

  1. the script is its own config file
  2. a named export, read at init
  3. export const options = { ... }
  4. root keys: vus, duration, stages, scenarios

basics

~20 s

k6 has no separate configuration file format. A k6 script exports an object named options, k6 reads it once at init, and its root keys - vus, duration, stages, scenarios, thresholds, tags - become the run configuration.

solid answer

~40 s

A k6 script configures itself. You add a named export called `options` - idiomatically `export const options = { ... }` - and k6 evaluates the script once before any virtual user exists, then decodes that object into the run configuration. Root keys include `vus`, `duration`, `stages`, `scenarios`, `thresholds`, `tags`, `rps`, `discardResponseBodies` and `summaryTrendStats`. Because it is ordinary JavaScript sitting in the script file, load settings are reviewed and version-controlled alongside the code they exercise. Many of the same settings also have a `k6 run` flag - `--vus`/`-u`, `--duration`/`-d`, `--stage`/`-s`, `--tag` - so a committed script can be run once at a different size without editing the file. A few keys, notably `thresholds` and `scenarios`, have no flag at all.

code

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

export const options = {
  vus: 10,
  duration: '5m',
  rps: 200,
  discardResponseBodies: true,
  tags: { service: 'checkout' },
  thresholds: { http_req_duration: ['p(95)<500'] },
};

export default function () {
  http.get('https://quickpizza.grafana.com/');
}

go deeper

for a junior

Be able to write the export from memory and name what vus, duration and stages do. Knowing that the settings live in the script itself, not in a separate config file, is most of the answer at this level.

for a middle

Explain the mechanics: k6 evaluates the script once before any VU exists, serialises the exported value and decodes it, so the object must be JSON-shaped data and is read once per run rather than per VU.

for a senior

Show you know which keys have no command-line flag, and why that shapes how a team runs k6 in CI. Being able to say that thresholds and scenarios must be committed is the production-relevant half.

for a principal

The tradeoff is what the committed object should fix and what the invocation is allowed to vary. Fixing too much makes one-off runs need code changes; fixing too little makes runs unreproducible from the repository alone.

## The script is the configuration k6 does not read a separate settings file before it reads your test. A k6 test is a JavaScript module, and one of the things that module exports is an object named `options`. Everything the run needs to know that is not test logic - how many virtual users, for how long, what to tag the metrics with, what to assert - is a key in that object, in the same file, in the same commit as the requests it configures. The name is the contract. k6 looks up the module export called `options`: ```javascript export const options = { vus: 10, duration: '30s' }; ``` `export let options = { ... }` behaves identically, and in base compatibility mode `module.exports.options = { ... }` does too. `const` is convention, not a requirement. ## When k6 reads it k6 evaluates the script once, in a throwaway init runtime, **before any virtual user exists**. It takes the exported value, serialises it to JSON, and decodes that JSON into its own internal options structure. Three consequences follow, and they explain most surprises: 1. The object may be **computed** rather than written as a literal, because it is ordinary JavaScript that runs before the decode - the value just has to exist by the time the module finishes evaluating. 2. It must reduce to **JSON-shaped data**. A value that JSON cannot represent is not configuration k6 can read, so the object holds plain objects, arrays, strings, numbers and booleans and nothing more. 3. It is read **once for the whole run**, not per VU and not per iteration. A computed `options` therefore cannot vary between virtual users: every VU is created after the decode has already happened. ## The root keys The object is flat: keys sit at its top level, in camelCase. The ones you meet first: - **`vus`** - how many virtual users to run concurrently. Defaults to 1. - **`duration`** - how long the run lasts, as a duration string such as `'30s'` or `'5m'`. - **`stages`** - an array of `{ duration, target }` steps, for a run whose VU count changes over time. - **`scenarios`** - a map of named, independently configured workloads, for anything the three keys above cannot express. - **`thresholds`** - the pass rules the run is judged against. - **`tags`** - an object of key/value pairs attached to every metric sample the run emits. - **`rps`** - a cap on HTTP requests per second shared across all VUs; `0`, the default, means unlimited. - **`discardResponseBodies`** - `false` by default; set it to `true` and k6 reads response bodies without keeping them. - **`summaryTrendStats`** - which statistics the end-of-test summary prints for timing metrics. There are many more - `httpDebug`, `insecureSkipTLSVerify`, `maxRedirects`, `noConnectionReuse`, `setupTimeout`, `userAgent`, `systemTags` and others - but the list above covers almost every real script. ## The same setting, from the command line Most root keys have a matching `k6 run` flag, and the flag name is the kebab-case form of the camelCase key. Two of them are deliberately singular, because the flag is repeatable while the key takes a collection: | `options` key | `k6 run` flag | note | |---|---|---| | `vus` | `--vus`, `-u` | default `1` | | `duration` | `--duration`, `-d` | | | `iterations` | `--iterations`, `-i` | | | `stages` (array) | `--stage`, `-s` | flag is singular and repeatable | | `rps` | `--rps` | `0` means unlimited | | `tags` (object) | `--tag NAME=VALUE` | flag is singular and repeatable | | `discardResponseBodies` | `--discard-response-bodies` | | | `summaryTrendStats` | `--summary-trend-stats` | | | `thresholds` | *(no flag)* | script or a `--config` JSON file only | | `scenarios` | *(no flag)* | script or a `--config` JSON file only | So a script that declares `vus: 10, duration: '5m'` can still be run once as `k6 run --vus 1 --duration 10s script.js` for a smoke check, without touching the file. What you cannot do from the command line is add a threshold or a scenario: those two keys have no flag in k6 v2, which is a good reason to think of the exported object as the primary home for configuration and the flags as the escape hatch. ## What is different in k6 v2 Cloud settings live under the root **`cloud`** key. The older `options.ext.loadimpact` block was removed in k6 v2.0.0 and is no longer read, so a script carrying one is silently configuring nothing. Feature flags are the one documented exception to "options configures the run": a `features` key in the exported object is not honoured, and k6 logs a warning telling you to use `--features`, `K6_FEATURES` or the JSON config file instead.

  • Does k6 require `export const options`, or will another export form work?
    k6 looks up the module export whose name is `options`; the declaration form is yours. `export const options = { ... }` is the convention, `export let options = { ... }` is equivalent, and in base compatibility mode `module.exports.options = { ... }` works too. Renaming the export is what breaks it - k6 will simply find no options and run with defaults.
  • Which k6 root options keys cannot be set from a `k6 run` flag?
    `thresholds`, `scenarios` and `cloud` have no command-line flag in k6 v2. They can only come from the script's exported `options` object or from a JSON file passed with `--config`. That is why a k6 suite's pass rules and its workload shape effectively have to be committed rather than improvised at the prompt.
  • Where do cloud settings go in a k6 v2 options object?
    Under the root `cloud` key. The `options.ext.loadimpact` block that older k6 material shows was removed in k6 v2.0.0. `ext` still parses as a root key, so an `ext.loadimpact` block does not fail the run - it is simply ignored, which makes it a quiet way to lose configuration when porting an old script.

saying these in an interview costs you the question

  • Thinks k6 needs a separate YAML or XML configuration file
  • Says k6 re-reads the options object once per iteration
  • Assumes every options key has a matching k6 run flag
  • Puts cloud settings under ext.loadimpact, removed in k6 v2.0.0
  • Calls the CLI flag --stages; k6's flag is singular --stage
open as a page

In k6, what happens if a key in the exported `options` object is misspelled?

level: middleimportance: should knowfreq 52%

basics

~20 s

k6 logs one warning - There were unknown fields in the options exported in the script - and runs anyway with the default for the setting you meant. A misspelled root key never stops the run, so the run silently ignores it.

open as a page

In k6, what happens when an exported `options` object sets both `stages` and `scenarios`?

level: seniorimportance: should knowfreq 45%

basics

~20 s

k6 refuses to start. It reports that using stages and scenarios options simultaneously is not allowed and exits 104, invalid configuration, before any request is sent - because stages is shorthand that k6 would have to turn into a scenario itself.

open as a page

For a k6 suite in CI, which settings belong in the exported `options` object rather than on the command line?

level: principalimportance: should knowfreq 40%

basics

~20 s

k6 settles part of it: thresholds, scenarios and cloud have no k6 run flag, so they can only live in the script or a --config JSON file. The flags carry the size knobs - vus, duration, stage, tag.

open as a page

In k6, what does `exec.test.options` give you that the exported `options` object does not?

level: middleimportance: nice to knowfreq 38%

basics

~20 s

exec.test.options, from the k6/execution module, is the consolidated and derived configuration the run is actually using - command-line overrides included - as a read-only object. The exported options object is only what the script declared.

open as a page