k6 Tutorial — Modern Load Testing in JavaScript (2026)
Get productive with k6 in an hour: scripting, stages, thresholds, checks, and the Grafana Cloud output that replaces JMeter for teams shipping to Kubernetes.

Last updated 2026-07-20 · 12 min read · By Avinash K
k6 replaced JMeter as the default load-test tool for cloud-native teams because scripts are JavaScript, results stream to Grafana, and one binary runs anywhere. This tutorial takes you from install to a production CI pipeline with meaningful thresholds.
Key takeaways
- Install k6 and run your first load test in 5 minutes.
- Stages, VUs, and iterations — the model you must understand.
- Thresholds and checks — how to fail a build on p95 latency.
- Output to Grafana Cloud and integrate into GitHub Actions.
1. Install and first test
brew install k6 # macOS
choco install k6 # Windows
sudo apt install k6 # Debian/Ubuntu
# script.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
vus: 10,
duration: '30s',
};
export default function () {
const res = http.get('https://api.example.com/health');
check(res, { 'status is 200': (r) => r.status === 200 });
sleep(1);
}
# run
k6 run script.js2. Stages — ramp-up and hold
export const options = {
stages: [
{ duration: '2m', target: 100 }, // ramp to 100 VUs
{ duration: '5m', target: 100 }, // hold
{ duration: '2m', target: 500 }, // spike
{ duration: '5m', target: 500 }, // hold
{ duration: '2m', target: 0 }, // ramp down
],
};Match stages to a real user pattern. See our performance strategy guide for how to derive stages from prod metrics.
3. Thresholds — fail the build on regressions
export const options = {
thresholds: {
http_req_failed: ['rate<0.01'], // < 1% errors
http_req_duration: ['p(95)<500', 'p(99)<1500'], // p95 < 500ms
checks: ['rate>0.99'], // 99% checks pass
},
};k6 exits non-zero when thresholds fail — perfect for CI gating.
4. Scenarios — realistic mixes
export const options = {
scenarios: {
browse: { executor: 'ramping-vus', stages: [...], exec: 'browse' },
checkout: { executor: 'constant-arrival-rate', rate: 10,
timeUnit: '1s', duration: '5m', preAllocatedVUs: 20, exec: 'checkout' },
},
};
export function browse() { http.get('/products'); }
export function checkout() { http.post('/orders', payload); }5. Output to Grafana Cloud + CI
# Local Grafana + InfluxDB
k6 run --out influxdb=http://localhost:8086/k6 script.js
# Grafana Cloud k6
K6_CLOUD_TOKEN=... k6 cloud script.js
# GitHub Actions
- uses: grafana/k6-action@v0.3.1
with:
filename: script.js
flags: --out cloudSee the official k6 docs and compare with JMeter to choose per project.