Skip to main content

API Load Testing with k6

k6 is the developer-first load testing tool that runs JavaScript scripts, scales to millions of requests, and integrates cleanly into CI/CD. This guide covers everything from first run to production SLA enforcement.

✓ HTTP / WebSocket / gRPC ✓ Thresholds & SLA enforcement ✓ Ramp-up stages ✓ CI/CD integration

Installation

# macOS
brew install k6

# Ubuntu/Debian
sudo apt-get install k6

# Windows (via Chocolatey)
choco install k6

# Docker (no install needed)
docker run --rm -i grafana/k6 run - < script.js

Basic Load Test Script

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

export const options = {
  // Ramp up: 0 → 50 VUs in 1m, hold 5m, ramp down 1m
  stages: [
    { duration: '1m', target: 50 },
    { duration: '5m', target: 50 },
    { duration: '1m', target: 0  },
  ],
  // SLA thresholds — test fails if any is breached
  thresholds: {
    'http_req_duration': ['p(95) < 500', 'p(99) < 1000'],  // ms
    'http_req_failed':   ['rate < 0.01'],                   // < 1% errors
  },
};

export default function () {
  const BASE_URL = 'https://api.example.com';

  // GET request
  const res = http.get(`${BASE_URL}/users`, {
    headers: { Authorization: 'Bearer test-token' },
  });

  check(res, {
    'status is 200':         (r) => r.status === 200,
    'response time OK':      (r) => r.timings.duration < 500,
    'has users array':       (r) => JSON.parse(r.body).users !== undefined,
  });

  sleep(1); // think time between iterations
}
# Run the test
k6 run load-test.js

# Quick smoke test (1 VU, 10 iterations)
k6 run --vus 1 --iterations 10 load-test.js

# Output results as JSON
k6 run --out json=results.json load-test.js

POST with Authentication Flow

// auth-flow.js
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  vus: 100,
  duration: '5m',
  thresholds: {
    'http_req_duration{name:login}':     ['p(95) < 300'],
    'http_req_duration{name:dashboard}': ['p(95) < 200'],
  },
};

export default function () {
  // Step 1: Login
  const loginRes = http.post(
    'https://api.example.com/auth/login',
    JSON.stringify({ email: '[email protected]', password: 'pass123' }),
    {
      headers: { 'Content-Type': 'application/json' },
      tags: { name: 'login' },   // tag for per-endpoint thresholds
    }
  );
  check(loginRes, { 'login 200': (r) => r.status === 200 });

  const token = loginRes.json('token');

  // Step 2: Authenticated request
  const dashRes = http.get(
    'https://api.example.com/dashboard',
    {
      headers: { Authorization: `Bearer ${token}` },
      tags: { name: 'dashboard' },
    }
  );
  check(dashRes, { 'dashboard 200': (r) => r.status === 200 });

  sleep(2);
}

Load Test Types and When to Use Each

Test Type VU Pattern Duration Purpose
Smoke test1-5 VUs1-2 minVerify script works, no errors
Load testRamp to expected VUs5-30 minValidate performance under normal load
Stress testRamp beyond capacity15-60 minFind breaking point, error behavior
Spike test0 → max instantly5-15 minSudden traffic surge (flash sale, viral)
Soak testModerate VUs steady2-24 hoursMemory leaks, connection pool exhaustion

CI/CD Integration (GitHub Actions)

# .github/workflows/load-test.yml
name: API Load Test
on:
  workflow_dispatch:  # manual trigger
  schedule:
    - cron: '0 2 * * 1'  # every Monday at 2am
jobs:
  k6-load-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: grafana/setup-k6-action@v1  # official k6 action
      - name: Run load test
        run: k6 run --out json=results.json load-test.js
        env:
          API_BASE_URL: ${{ vars.STAGING_API_URL }}
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: k6-results
          path: results.json

Frequently Asked Questions

What is k6 and how is it different from JMeter or Locust?▼

k6 is a modern, developer-focused load testing tool written in Go that runs JavaScript test scripts. Unlike JMeter (Java, XML configuration, GUI-heavy), k6 scripts are plain JavaScript files that version-control cleanly and integrate naturally into CI/CD pipelines. Unlike Locust (Python, concurrent greenlets), k6 uses Go goroutines under the hood, giving it dramatically lower resource consumption per virtual user — you can run thousands of VUs on a laptop that would struggle with Locust. k6 also has built-in thresholds that fail the test if SLA metrics are breached.

What is the difference between VUs and RPS in k6?▼

VUs (Virtual Users) represent concurrent simulated users — each VU runs through your scenario sequentially. RPS (Requests Per Second) is a throughput metric derived from VU count and request duration. With 100 VUs each sending one request per second, you get approximately 100 RPS. With 100 VUs sending requests with 200ms response times, you get roughly 500 RPS. k6 lets you control either directly: use constant-vus executor to fix VU count, or use constant-arrival-rate executor to fix RPS regardless of response time.

How do I set performance thresholds in k6?▼

Define thresholds in your script's options object as conditions on metric names. Common thresholds: http_req_duration for latency (e.g., p95 < 500 for p95 under 500ms), http_req_failed for error rate (e.g., rate < 0.01 for under 1% errors). If any threshold is breached, k6 exits with a non-zero code, failing your CI pipeline. You can also set thresholds per URL group using tagged metrics.

Can k6 test WebSocket or gRPC APIs?▼

Yes. k6 has native WebSocket support via the k6/ws module — use ws.connect() to open a connection and send/receive messages in a callback. For gRPC, import k6/net/grpc, load your proto definitions with client.load(), and call methods with client.invoke(). HTTP/2 is supported automatically when the server supports it. k6 also has modules for Redis, Kafka, and SQL in the k6 extension ecosystem (xk6).

How do I integrate k6 with CI/CD and alert on regressions?▼

Add k6 to CI by installing k6 (apt/brew/docker) and running k6 run --out json=results.json script.js. The exit code is non-zero if any threshold fails, so CI naturally fails on SLA breaches. For trend tracking, output results to Prometheus (k6 --out experimental-prometheus-rw), Grafana Cloud (k6 --out cloud), InfluxDB + Grafana, or Datadog (k6 --out datadog). Store baseline metrics and alert when p95 or error rate regresses beyond a tolerance.

What is the k6 stages array and how do I model realistic traffic?▼

The stages array in options lets you define a ramp-up shape for VU count over time. Each stage specifies a duration and target VU count. A typical load test ramps up gradually (0→50 VUs over 2 minutes), holds steady load (50 VUs for 5 minutes), then ramps down. For realistic traffic patterns, use the ramping-arrival-rate executor to model request-per-second curves. Spike tests go from 0 to max VUs in seconds. Soak tests hold moderate load for hours to expose memory leaks.

Share this tool: X / Twitter LinkedIn
✓ 60,000+ developers use DevPlaybook ★★★★★ 4.8 / 5 on Gumroad ✓ MIT licensed · Instant download ✓ No login required

Related Products

on Gumroad

You Might Also Need

More Free Tools

OpenAPI Validator k6 Script Generator API Response Mock Generator API Response Time Tester OpenAPI Schema Validator k6 Load Test Script Generator OpenAPI Mock Generator API Test Case Generator Web Performance Checklist API Request Builder API Mock Server Config Generator Jest Testing Framework Guide API Rate Limit Calculator API Response Formatter & Analyzer HTTP API Tester LLM Cost Calculator AI Prompt Cost Calculator REST API Request Builder Lighthouse Score Simulator Vitest Guide — Vite-native Testing Cypress Frontend Testing Guide LLM Prompt Cost Calculator API Response Mocker AI Rate Limit Calculator Web Vitals Budget Planner Core Web Vitals Guide API Key Generator AI Doc Generator — Pro Tool AI Unit Test Generator — Pro Tool HTTP Methods Reference HTTP Code Snippet Generator HTTP Status Code Reference HTTP Status Code Reference JSON Diff Viewer JSON Diff Rate Limiter Tester API Changelog Generator HTTP Mock Response Builder Web Vitals Scorer Rate Limit Calculator CORS Policy Builder SQL Index Advisor HAR Diff Analyzer HTTP Status Code Lookup MySQL Query Explainer PostgreSQL EXPLAIN Analyzer HTTP Status Code Lookup Vue Component Generator HTTP Status Code Reference LLM Context Window Calculator LLM Token Counter HTTP/2 Server Push Headers Builder Playwright E2E Test Generator Web Vitals Analyzer Prompt Token Estimator Database Index Analyzer Playwright E2E Testing Guide Mock Service Worker (MSW) API Mocking Guide Pulumi Modern IaC Guide Core Web Vitals Calculator Database Index Advisor HTML5 Canvas API Playground LLM Benchmark Calculator Prompt Injection Tester Token Context Calculator OpenAI Function Calling Generator Core Web Vitals Budget Calculator Bundle Size Budget Calculator Image Optimization Calculator TTFB Analyzer Token Counter & Cost Estimator AI API Rate Limit Calculator Database Query Cost Analyzer

Related Articles

Enjoying this tool? Get more like it.

Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.

DevPlaybook Pro 7 days free

Unlock AI-Powered Dev Tools

  • ⚡ AI Code Review, Doc Generator & SQL Builder
  • ⚡ All premium templates & early access
  • ⚡ Member discounts on Gumroad products
Start Free Trial →

$9/mo after trial · Cancel anytime

Want the full toolkit?

Get DevPlaybook Pro

Every template, guide, boilerplate, and automation script in one bundle. 13 premium products — grab them all at once and save big.

$79
$241 separately Save $162 (67% off)
Get DevPlaybook Pro — $79 →

MIT licensed · Instant download · No subscription

See what's included → Browse all deals →