Skip to content
Latchkey

k6 Thresholds: Fail the Build on SLOs

k6 thresholds define SLO pass/fail conditions on metrics; if any is breached, k6 exits with code 99 so CI fails.

Thresholds are how a k6 run becomes a gate. You express the SLO (for example p95 under 500ms, error rate under 1 percent) and k6 turns a breach into a failing build.

What it does

A thresholds object in the script's options maps a metric to one or more pass conditions. If a condition fails at the end of the run, k6 exits non-zero (code 99). With abortOnFail, the run stops as soon as the threshold is crossed.

Common usage

script.js
export const options = {
  vus: 50, duration: '1m',
  thresholds: {
    http_req_duration: ['p(95)<500'],
    http_req_failed: ['rate<0.01'],
    // stop early if it blows past the limit
    'http_req_duration{kind:html}': [
      { threshold: 'p(99)<1500', abortOnFail: true },
    ],
  },
};

Options

ExpressionWhat it does
p(95)<50095th percentile under 500ms
rate<0.01Failure rate under 1 percent
avg<200 / med<300Average or median bound
count<100Bound on a counter metric
abortOnFail: trueStop the run on breach (object form)
delayAbortEval: '10s'Wait before evaluating abort

In CI

Thresholds are the reason k6 belongs in a pipeline: a breached p95 or error rate produces exit code 99 and fails the job automatically, with no extra parsing. Keep the SLOs in the script under version control so changes are reviewed.

Common errors in CI

The job fails with "level=error msg=\"thresholds on metrics 'http_req_duration' have been crossed\"" and k6 exits 99; that is the gate working. If thresholds never trip, the metric name is misspelled or the sub-metric tag (the {kind:html} part) matched nothing. A threshold on a custom metric you never recorded is silently inactive.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →