Load Testing Development for Websites (k6)
k6 is a modern load testing tool from Grafana Labs. Scenarios in JavaScript, built-in metrics, integration with Grafana/InfluxDB. Optimal for API load testing and performance SLA verification.
Installation
# Windows
winget install k6
# macOS
brew install k6
# Linux
sudo apt install k6
Basic Scenario
// scripts/smoke-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate } from 'k6/metrics';
const errorRate = new Rate('error_rate');
export const options = {
vus: 10, // 10 virtual users
duration: '30s', // for 30 seconds
thresholds: {
http_req_duration: ['p(95)<500'], // 95% of requests faster than 500ms
http_req_failed: ['rate<0.01'], // less than 1% errors
error_rate: ['rate<0.05'],
},
};
export default function () {
const res = http.get('https://staging.example.com/api/products');
const ok = check(res, {
'status is 200': r => r.status === 200,
'response time < 500ms': r => r.timings.duration < 500,
'has data array': r => r.json('data') !== undefined,
});
errorRate.add(!ok);
sleep(1);
}
Ramping Scenario (Increasing Load)
export const options = {
stages: [
{ duration: '2m', target: 10 }, // ramp-up: 0→10 VU for 2 minutes
{ duration: '5m', target: 10 }, // stay: 10 VU for 5 minutes
{ duration: '2m', target: 50 }, // ramp-up to 50 VU
{ duration: '5m', target: 50 }, // stay: 50 VU for 5 minutes
{ duration: '2m', target: 100 }, // peak load
{ duration: '5m', target: 100 },
{ duration: '2m', target: 0 }, // ramp-down
],
thresholds: {
http_req_duration: ['p(99)<2000'],
http_req_failed: ['rate<0.02'],
},
};
Scenario with Authorization
import http from 'k6/http';
import { check, group, sleep } from 'k6';
import { SharedArray } from 'k6/data';
// Load test users from file
const users = new SharedArray('users', () =>
JSON.parse(open('./data/users.json'))
);
export default function () {
const user = users[Math.floor(Math.random() * users.length)];
// Login
let loginRes;
group('Login', () => {
loginRes = http.post('https://staging.example.com/api/auth/login',
JSON.stringify({ email: user.email, password: user.password }),
{ headers: { 'Content-Type': 'application/json' } }
);
check(loginRes, {
'login successful': r => r.status === 200,
'token received': r => r.json('access_token') !== undefined,
});
});
const token = loginRes.json('access_token');
const headers = { Authorization: `Bearer ${token}` };
sleep(1);
// Browse Products
group('Browse Products', () => {
const res = http.get('https://staging.example.com/api/products?page=1', { headers });
check(res, { 'products loaded': r => r.status === 200 });
sleep(2);
});
// Create Order
group('Create Order', () => {
const res = http.post('https://staging.example.com/api/orders',
JSON.stringify({ product_id: 1, quantity: 1 }),
{ headers: { ...headers, 'Content-Type': 'application/json' } }
);
check(res, { 'order created': r => r.status === 201 });
});
sleep(1);
}
Sending Metrics to Grafana
# InfluxDB + Grafana
k6 run --out influxdb=http://localhost:8086/k6 script.js
# k6 Cloud
k6 cloud script.js
# Grafana Cloud k6
K6_CLOUD_TOKEN=xxx k6 run --out cloud script.js
Interpreting Results
Results show key metrics: http_req_duration (response time), http_req_failed (error rate), custom metrics like error_rate. Pass/fail is determined by thresholds defined in options.
Implementation Timeline
Basic set of load testing scenarios (smoke, load, stress, soak): 3–5 days.







