JMeter is a Java GUI from 2003. Artillery uses YAML. Locust needs Python. You want to load test your API but the tooling friction stops you.
What if load tests were just JavaScript files you run from the terminal?
That's k6. Write tests in JavaScript/TypeScript, execute locally or in the cloud, get instant performance metrics.
Quick Start
# macOS
brew install k6
# Or download from https://k6.io
Your First Load Test
// load-test.js
import http from "k6/http";
import { check, sleep } from "k6";
export const options = {
stages: [
{ duration: "30s", target: 20 }, // Ramp up to 20 users
{ duration: "1m", target: 20 }, // Stay at 20 users
{ duration: "10s", target: 0 }, // Ramp down
],
thresholds: {
http_req_duration: ["p(95)<500"], // 95% of requests under 500ms
http_req_failed: ["rate<0.01"], // Error rate under 1%
},
};
export default function () {
const res = http.get("https://api.example.com/users");
check(res, {
"status is 200": (r) => r.status === 200,
"response time < 500ms": (r) => r.timings.duration < 500,
"has users": (r) => JSON.parse(r.body).length > 0,
});
sleep(1);
}
k6 run load-test.js
Test Patterns
Spike Test
export const options = {
stages: [
{ duration: "10s", target: 100 }, // Sudden traffic spike
{ duration: "1m", target: 100 },
{ duration: "10s", target: 0 },
],
};
Stress Test
export const options = {
stages: [
{ duration: "2m", target: 100 },
{ duration: "5m", target: 200 },
{ duration: "2m", target: 300 },
{ duration: "5m", target: 400 }, // Find the breaking point
{ duration: "2m", target: 0 },
],
};
API Workflow Test
export default function () {
// Login
const loginRes = http.post("https://api.example.com/auth/login",
JSON.stringify({ email: "test@test.com", password: "pass" }),
{ headers: { "Content-Type": "application/json" } }
);
const token = JSON.parse(loginRes.body).token;
// Authenticated request
const headers = { Authorization: `Bearer ${token}` };
const products = http.get("https://api.example.com/products", { headers });
check(products, { "got products": (r) => r.status === 200 });
// Create order
const order = http.post("https://api.example.com/orders",
JSON.stringify({ productId: "123", quantity: 1 }),
{ headers: { ...headers, "Content-Type": "application/json" } }
);
check(order, { "order created": (r) => r.status === 201 });
sleep(1);
}
k6 vs Other Load Testing Tools
| Feature | k6 | JMeter | Artillery | Locust |
|---|---|---|---|---|
| Language | JavaScript | GUI/XML | YAML | Python |
| Protocol | HTTP, WS, gRPC | HTTP, JDBC, FTP | HTTP, WS | HTTP |
| CLI-first | Yes | No (GUI) | Yes | Yes |
| CI-friendly | Excellent | Poor | Good | Good |
| Performance | Go engine (fast) | Java (heavy) | Node.js | Python |
Start here: k6.io
Need custom data extraction, scraping, or automation? I build tools that collect and process data at scale — 78 actors on Apify Store and 265+ open-source repos. Email me: Spinov001@gmail.com | My Apify Actors
Top comments (0)