RousselTMLEARNING

Article · Grafana k6: load and performance testing

Writing k6 scripts

1. Anatomy of a script #

Init, setup, default, teardown.

First script #

Lifecycle of a k6 test
Only the default function is repeated by each virtual user (VU).
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  vus: 10,            // utilisateurs virtuels simultanés
  duration: '30s',
};

export default function () {
  const res = http.get('http://localhost:8080/get');
  check(res, {
    'statut 200': (r) => r.status === 200,
    'moins de 300 ms': (r) => r.timings.duration < 300,
  });
  sleep(1);           // temps de réflexion de l'utilisateur
}
k6 run script.js
Good practice: A check does not fail the test: it counts successes and failures. To fail a test, use thresholds.

2. Realistic requests #

Data, headers, groups.

Examples #

import http from 'k6/http';
import { group } from 'k6';

export function setup() {        // exécuté une fois : par exemple, obtenir un jeton
  const res = http.post('http://api/login', JSON.stringify({ user: 'demo', pass: 'demo' }),
                        { headers: { 'Content-Type': 'application/json' } });
  return { token: res.json('token') };
}

export default function (data) {
  const params = { headers: { Authorization: `Bearer ${data.token}` }, tags: { name: 'commande' } };
  group('parcours achat', () => {
    http.get('http://api/produits');
    http.post('http://api/panier', JSON.stringify({ id: 42 }), params);
  });
}
Common mistake: URLs with identifiers (/produits/123) create one metric series per URL. Give them a common name tag ({ tags: { name: 'produit' } }) to keep results readable.

3. Scenarios and executors #

Modeling the load.

VUs or rate? #

Executors decide how load is generated. Two families:

ExecutorModelUsage
constant-vus, ramping-vusClosed: N users chaining iterationsSimulating user sessions
constant-arrival-rate, ramping-arrival-rateOpen: N iterations per second, no matter whatMeasuring an API at a given rate
shared-iterations, per-vu-iterationsFixed number of iterationsBatch jobs, functional tests
Good to know: With a closed model, if the service slows down, each VU makes fewer requests: the load drops and hides the problem. An open model (arrival rate) keeps the rate and reveals saturation.

Several scenarios #

export const options = {
  scenarios: {
    navigation: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '2m', target: 50 },   // montée
        { duration: '5m', target: 50 },   // plateau
        { duration: '1m', target: 0 },    // descente
      ],
      exec: 'parcours',
    },
    api: {
      executor: 'constant-arrival-rate',
      rate: 200, timeUnit: '1s',          // 200 requêtes par seconde
      duration: '8m',
      preAllocatedVUs: 50, maxVUs: 300,
      exec: 'appelApi',
    },
  },
};
export function parcours() { /* ... */ }
export function appelApi() { /* ... */ }

📄 Writing k6 scripts: requests, checks, scenarios and executors →

My progress

  • ⏱ Estimated time : ≈ 10 min

Sign in to track your progress and take notes. Sign in

💬 Questions about this lesson

No questions yet: be the first to ask for help or share your configuration.

Ask a question about this lesson →

Recommended Articles

Linting Dockerfiles with Hadolint and docker build --check

Spot Dockerfile errors and bad practices before building: Hadolint, its rules, thresholds, and Bu...

Dynatrace Synthetic Monitoring: complete guide and best practices

Learn how to use Dynatrace Synthetic Monitoring to proactively monitor your applications, from th...

Measuring SLIs with Prometheus

Implement availability and latency SLIs with Prometheus: required metrics, ratio queries, histogr...

Anatomy of HAProxy configuration, clustering and high availability

Understand the structure of an haproxy.cfg file: the global, defaults, frontend (high performance...

Measuring DevOps performance: DORA metrics, SPACE and continuous improvement

Measure and improve delivery performance: the DORA metrics (deployment frequency, lead time, chan...

Mastering variables in Grafana: make your dashboards dynamic

Learn how to use variables to create interactive, reusable dashboards. Discover the difference be...

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 ...

Alerting on error budget burn rate (multi-window burn rate)

Why alert on burn rate rather than a threshold, and how to build the multi-window, multi-burn-rat...

HAProxy in Kubernetes: the high-performance Ingress Controller

Discover in depth how HAProxy integrates with Kubernetes: direct-to-pod architecture, hot update ...

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!