1. Built-in metrics #
What k6 measures.
Main metrics #
| Metric | Type | Meaning |
|---|---|---|
http_req_duration | Trend | Total request duration (sending + waiting + receiving) |
http_req_waiting | Trend | Time to first byte (TTFB) |
http_req_failed | Rate | Share of failed requests (by default: status outside 200-399) |
http_reqs | Counter | Number of requests |
iterations, iteration_duration | Counter, Trend | Scenario iterations |
vus, vus_max | Gauge | Active virtual users |
checks | Rate | Share of successful checks |
dropped_iterations | Counter | Iterations not started for lack of VUs (open model) |
Common mistake: Ifdropped_iterationsis non-zero, k6 could not generate the requested load: increasemaxVUsor 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.jsThe handleSummary(data) function lets you produce your own report (HTML, JUnit, Markdown) at the end of the test.
