DEV Community

Alex Spinov
Alex Spinov

Posted on

k6 Has a Free API — Load Testing for Developers Who Write JavaScript

k6 is a load testing tool where you write tests in JavaScript. Built by Grafana Labs, it's fast (Go runtime), scriptable (JS API), and integrates with your CI/CD pipeline.

Why k6?

  • JavaScript tests — write tests in JS, run in Go (fast!)
  • Developer-first — version control your tests, run in CI
  • Built-in metrics — response time, throughput, error rate
  • Extensions — Redis, SQL, Kafka, browser testing

Quick Start

# Install
brew install k6  # macOS
apt install k6   # Ubuntu

# Or Docker
docker run -i grafana/k6 run - <script.js
Enter fullscreen mode Exit fullscreen mode

Basic Test

// test.js
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  vus: 10,        // 10 virtual users
  duration: '30s', // for 30 seconds
};

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,
    'body has users': (r) => JSON.parse(r.body).length > 0,
  });

  sleep(1);
}
Enter fullscreen mode Exit fullscreen mode
k6 run test.js
Enter fullscreen mode Exit fullscreen mode

Load Patterns

export const options = {
  stages: [
    { duration: '1m', target: 20 },   // Ramp up to 20 users
    { duration: '3m', target: 20 },   // Stay at 20 users
    { duration: '1m', target: 100 },  // Spike to 100
    { duration: '2m', target: 100 },  // Hold 100
    { duration: '1m', target: 0 },    // Ramp down
  ],
  thresholds: {
    http_req_duration: ['p(95)<500'],  // 95% under 500ms
    http_req_failed: ['rate<0.01'],     // <1% errors
  },
};
Enter fullscreen mode Exit fullscreen mode

POST Requests with JSON

import http from 'k6/http';

export default function () {
  const payload = JSON.stringify({
    name: `User ${__VU}`,
    email: `user${__VU}@test.com`,
  });

  const params = {
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer token123',
    },
  };

  const res = http.post('https://api.example.com/users', payload, params);
  check(res, { 'created': (r) => r.status === 201 });
}
Enter fullscreen mode Exit fullscreen mode

Scenarios

export const options = {
  scenarios: {
    browse: {
      executor: 'constant-vus',
      vus: 50,
      duration: '5m',
      exec: 'browsing',
    },
    purchase: {
      executor: 'ramping-arrival-rate',
      startRate: 1,
      timeUnit: '1s',
      preAllocatedVUs: 50,
      stages: [{ duration: '5m', target: 10 }],
      exec: 'purchasing',
    },
  },
};

export function browsing() {
  http.get('https://shop.example.com/products');
}

export function purchasing() {
  http.post('https://shop.example.com/checkout', payload);
}
Enter fullscreen mode Exit fullscreen mode

CI/CD Integration

# GitHub Actions
- name: Run k6 load test
  uses: grafana/k6-action@v0.3.1
  with:
    filename: tests/load.js
    flags: --out json=results.json
Enter fullscreen mode Exit fullscreen mode

Need to load test your APIs? Check out my Apify actors for web scraping that handles high load, or email spinov001@gmail.com for custom testing solutions.

k6, Artillery, or JMeter — which load testing tool do you use? Share below!

Top comments (0)