RousselTMLEARNING

DevOps

Thresholds, metrics and results of a k6 test

Read the summary of a k6 test, understand the built-in metrics (http_req_duration, http_req_failed, iterations), define thresholds aligned with SLOs and create custom metrics.

1. Built-in metrics #

What k6 measures.

Main metrics #

MetricTypeMeaning
http_req_durationTrendTotal request duration (sending + waiting + receiving)
http_req_waitingTrendTime to first byte (TTFB)
http_req_failedRateShare of failed requests (by default: status outside 200-399)
http_reqsCounterNumber of requests
iterations, iteration_durationCounter, TrendScenario iterations
vus, vus_maxGaugeActive virtual users
checksRateShare of successful checks
dropped_iterationsCounterIterations not started for lack of VUs (open model)
Common mistake: If dropped_iterations is non-zero, k6 could not generate the requested load: increase maxVUs or the test machine, otherwise the result is skewed.

2. Thresholds #

The test passes or fails.

Defining thresholds #

export const options = {
  thresholds: {
    http_req_failed: ['rate<0.01'],                    // moins de 1 % d'erreurs
    http_req_duration: ['p(95)<300', 'p(99)<800'],     // 95 % sous 300 ms
    'http_req_duration{name:commande}': ['p(95)<500'], // seuil sur un tag
    checks: ['rate>0.99'],
    http_reqs: [{ threshold: 'count>1000', abortOnFail: false }],
    'http_req_duration{scenario:api}': [{ threshold: 'p(99)<1000', abortOnFail: true, delayAbortEval: '30s' }],
  },
};

If a threshold is not met, k6 exits with exit code 99: the CI marks the step as failed.

Good practice: Align thresholds with your SLOs (see the SRE course): a load test then becomes proof that a version meets its objectives.

3. Custom metrics #

Measuring what matters to the business.

The four types #

import { Trend, Counter, Rate, Gauge } from 'k6/metrics';

const dureeCommande = new Trend('duree_commande', true);   // true = durée
const commandes = new Counter('commandes');
const paiementsRefuses = new Rate('paiements_refuses');

export const options = { thresholds: { paiements_refuses: ['rate<0.05'], duree_commande: ['p(95)<2000'] } };

export default function () {
  const debut = Date.now();
  const res = http.post('http://api/commande', '{}');
  dureeCommande.add(Date.now() - debut);
  commandes.add(1);
  paiementsRefuses.add(res.status === 402);
}

The end-of-test summary #

k6 run --summary-trend-stats="avg,p(90),p(95),p(99),max" script.js
k6 run --summary-export=resume.json script.js

The handleSummary(data) function lets you produce your own report (HTML, JUnit, Markdown) at the end of the test.

Related articles

Load testing with Grafana k6: why, and which types of tests

Why test performance before production, the types of tests (smoke, load, stress, spike, soak, breakpoint) and…

Writing k6 scripts: requests, checks, scenarios and executors

The structure of a k6 script (init, setup, default, teardown), HTTP requests, checks, groups and tags, and mo…

Observing a k6 test: Prometheus, Grafana and correlation with the system under test

Send k6 results to Prometheus (remote write) or via OpenTelemetry, visualize them in Grafana and correlate th…

Keep learning

Support us

♥ SUPPORT US

Support RousselTM Learning

Courses, articles, labs and certificates stay free with no intrusive ads. A voluntary contribution, of any amount you choose, pays for hosting, lab environments and new content.

Contribute with PayPal Any amount · card or PayPal accountLearn more
QR code PayPal
Or scan this QR code with your phone

Thank you, every contribution counts!