Rolling k6 out to several teams, what must you standardise because a k6 test is ordinary JavaScript?
answer
- the tool standardises little for you
- same binary on every runner
- one shared module layer
- no threshold means no verdict
- executor names are already fixed
basics
~20 sStandardise the binary every runner resolves to, the shared module layer teams import, and a rule that every test declares thresholds, since k6 exits zero when none exist. The executor vocabulary standardises itself: only six names are legal.
solid answer
~50 sBecause a k6 test is a JavaScript module rather than something the tool authors, nothing is standardised for you except what the binary refuses to accept. Three things need a decision. **The binary**: stock, or a build with extensions — and every laptop and runner must resolve to the same one. **The shared module layer**: tests reuse by ES `import`, so unless one repository owns the auth helpers, base URLs, tags and a common `options` fragment, every team writes its own. **A threshold policy**: k6 exits 99 only when a declared threshold is breached, and supplies no default, so a test with none always exits zero — "every test declares thresholds" has to be enforced in review or lint. One thing standardises itself: `executor` is a string with exactly six legal values in k6 v2, and an unrecognised one fails configuration parsing before any load runs.
code
javascript · 15 linesimport http from 'k6/http';
const teamDefaults = {
thresholds: { http_req_failed: ['rate<0.01'] },
};
export const options = {
...teamDefaults,
vus: 5,
duration: '10s',
};
export default function () {
http.get('https://quickpizza.grafana.com');
}go deeper
The point to remember: k6 does not impose a house style on tests. Anything shared between teams — helpers, options fragments, conventions — exists because someone built and published it.
Be able to name what the binary enforces versus what habit enforces. Executor names and the exit contract are fixed; test structure, shared modules and the result destination are not.
Show you have run this rollout: pin the binary, seed a shared module layer early, and add a mechanical check that a test declares thresholds, since k6 exits zero when none exist.
Argue where the line sits. Too little standardisation gives you five dialects and incomparable results; too much rebuilds the rigid authored-plan model you chose k6 to escape, without its tooling.
## Why this is a real question for k6 When a tool authors the test for you, its own vocabulary is the standard: everyone's artefact has the same shape because the tool would not let it be otherwise. k6 makes the opposite bet. The test is a JavaScript module, the configuration is an exported object, and reuse is `import`. That is a great deal of freedom, and freedom across five teams becomes five conventions unless somebody decides otherwise. So the adoption question is not "can k6 do this?" — it can — but "what will diverge if nobody owns it?" ## The four decisions to own 1. **Which binary.** If any team imports a module under `k6/x/`, the organisation now needs a built binary, published somewhere, resolved identically by every CI runner and every laptop. If nobody needs an extension, standardise on "the stock release, at this version" and say so explicitly — an unstated default is still a decision, just an unowned one. 2. **The shared module layer.** Decide which repository holds the modules every test imports: authentication, base URLs, a tagging convention, and a house `options` fragment teams spread into their own. Without it, five teams solve the same login flow five times and none of the solutions improve. 3. **A threshold policy.** k6 renders a verdict only when a threshold is declared. Nothing forces one, and a script with an empty `thresholds` block runs happily and exits zero. "Every test declares thresholds" therefore has to live in a review checklist or a lint rule, because the tool will never raise it. 4. **Where results go.** The run itself prints a terminal summary. Anything durable — a file, a dashboard, a time-series backend — is a choice, and if it is not made centrally each team makes a different one and nothing is comparable across them. ## What standardises itself - **The scheduling vocabulary.** In k6 v2 the `executor` key is a plain string, and exactly **six** executor names are registered in the binary. An unrecognised value fails configuration parsing before any load is generated, so no team can invent a seventh. This is the one axis you do not have to police. - **The exit contract.** A breached threshold exits **99** everywhere, on every machine, in every version of the same binary. Pipelines written against it do not need per-team variants. - **The module boundary.** Anything not in the binary's module set fails at load, so a team cannot quietly acquire a capability the others lack — the failure is loud and immediate. ## Where the effort actually lands | area | standardised by the tool | left to you | |---|---|---| | scheduling names | yes — six legal `executor` values | nothing; the set is closed | | verdict mechanics | yes — a breach exits 99 | whether a threshold exists at all | | test structure | no | a shared module layer and where it lives | | runtime identity | no | which binary build every runner resolves to | | result destination | no | one sink, chosen centrally | The pattern is worth naming: k6 standardises the things the binary can refuse, and standardises nothing that is merely a habit. Everything in the right-hand column is a habit until you write it down. ## The judgment call There is no single right answer here, and the trade is genuine. Standardise too little and you get five dialects, incomparable results, and a script that runs on one runner and not another. Standardise too much — a mandated wrapper library every test must go through, a bespoke internal CLI in front of `k6 run` — and you have quietly rebuilt the authored-plan model you chose k6 to avoid, with none of the tooling and all of the rigidity. The defensible middle is usually **pin the binary hard, share modules generously, mandate the verdict, and leave everything else to the teams** — because each of those lands somewhere different: - **The binary** is where divergence causes outages: a script that loads on one runner and not another is a pipeline failure, not a style disagreement. - **The shared layer** is where duplication compounds: the same login flow written five times never improves in any of the five. - **The verdict** is where silence looks like success: a test with no threshold reports green forever and nobody notices. - **Test structure, naming and file layout** are where local judgment costs little and central control buys nothing. - **The result destination** sits in between: cheap to unify early, painful once every team has a different one. Whichever line you draw, draw it before the second team starts — retrofitting a shared module layer across tests that already exist is far more expensive than seeding one, and asking a team to add thresholds to a suite that has been "green" for six months is a conversation nobody enjoys.
- How would you enforce that every k6 test declares thresholds?In review plus a mechanical check, because k6 never will. A small lint step that loads the script's exported `options` and fails when `thresholds` is missing or empty catches it before merge, which is far cheaper than discovering six months later that a green stage asserted nothing.
- What is the risk of building an internal wrapper CLI around k6 run for consistency?You gradually recreate the authored-plan model k6 was chosen to avoid. Teams lose the ability to read a test as plain JavaScript, the wrapper becomes an unowned dependency, and debugging gains a layer. Prefer shared importable modules, which teams can read and bypass, over a mandatory front door.
- Which of these decisions can safely be deferred?Test structure and naming conventions — they cost little to unify later and central control buys little. The binary and the threshold policy cannot be deferred: divergent binaries break pipelines, and tests without thresholds accumulate a backlog of runs that never asserted anything.
saying these in an interview costs you the question
- Assuming k6 enforces a house test structure across teams
- Believing each team can register its own executor names
- Thinking a k6 test without thresholds still fails on a bad run
- Mandating an internal wrapper CLI in front of every k6 run
- Treating the k6 version as enough to make runs reproducible
- Leaving the result destination to each team and expecting comparable numbers