Skip to content
Back to skills

K6

ASecurity

k6 performance and load testing. Covers writing test scripts in JavaScript/TypeScript, all test types (load/stress/spike/soak/smoke/breakpoint), thresholds, checks, scenarios, executors, extensions, result analysis, k6 Cloud execution, and CI/CD integration. Use when writing k6 tests, debugging test failures, setting up load testing pipelines, choosing executors/scenarios, or interpreting k6 results.

  • 268 stars
  • 0 votes
  • 0 copies
  • 6 views
  • Added June 11, 2026
developmentjavascripttypescriptgojavaphpbashtestingdebugginggitapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned June 11, 2026

npx -y skills add grafana/skills --skill k6 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of K6?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for K6
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/grafana-k6/badge)](https://www.skillsdirectory.com/skills/grafana-k6)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: k6
license: Apache-2.0
description: >
  k6 performance and load testing. Covers writing test scripts in JavaScript/TypeScript, all test types
  (load/stress/spike/soak/smoke/breakpoint), thresholds, checks, scenarios, executors, extensions,
  result analysis, k6 Cloud execution, and CI/CD integration. Use when writing k6 tests, debugging
  test failures, setting up load testing pipelines, choosing executors/scenarios, or interpreting k6 results.
---

# k6 Performance Testing

> **Docs**: https://grafana.com/docs/k6/latest/

## Quick Start

```bash
# Install
brew install k6                          # macOS
sudo apt install k6                      # Ubuntu/Debian
choco install k6                         # Windows

# Run a test
k6 run script.js
k6 run --vus 10 --duration 30s script.js
k6 run --out json=results.json script.js
```

## Basic Script Structure

```javascript
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  vus: 10,
  duration: '30s',
  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://test.k6.io');
  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time OK': (r) => r.timings.duration < 500,
  });
  sleep(1);
}
```

## Test Lifecycle

```javascript
export function setup() {
  // Runs once before all VUs — return data shared with VUs
  const token = getAuthToken();
  return { token };
}

export default function (data) {
  // Runs for each VU iteration — receives setup() return value
  http.get('https://api.example.com', {
    headers: { Authorization: `Bearer ${data.token}` },
  });
}

export function teardown(data) {
  // Runs once after all VUs finish
  console.log('Test complete');
}
```

## HTTP Requests

```javascript
import http from 'k6/http';

// GET
const res = http.get('https://api.example.com/users');

// POST with JSON body
const payload = JSON.stringify({ name: 'test', value: 42 });
const params = { headers: { 'Content-Type': 'application/json' } };
const res = http.post('https://api.example.com/users', payload, params);

// PUT / PATCH / DELETE
http.put(url, body, params);
http.patch(url, body, params);
http.del(url, null, params);

// Batch requests (parallel)
const responses = http.batch([
  ['GET', 'https://api.example.com/users'],
  ['GET', 'https://api.example.com/posts'],
]);

// With auth
const res = http.get(url, {
  headers: { Authorization: 'Bearer token123' },
});

// Form data
const res = http.post(url, { username: 'user', password: 'pass' });

// File upload
const binFile = open('./image.png', 'b');
const res = http.post(url, {
  file: http.file(binFile, 'image.png', 'image/png'),
  field: 'value',
});
```

## Checks and Thresholds

```javascript
import { check } from 'k6';

// Checks (soft assertions — don't stop test on failure)
const res = http.get(url);
check(res, {
  'status 200': (r) => r.status === 200,
  'body contains ID': (r) => r.body.includes('"id"'),
  'duration < 500ms': (r) => r.timings.duration < 500,
});

// Thresholds (hard pass/fail criteria)
export const options = {
  thresholds: {
    // HTTP metrics
    http_req_duration: ['p(90)<400', 'p(95)<800', 'avg<200'],
    http_req_failed: ['rate<0.05'],

    // Custom metric thresholds
    my_errors: ['count<10'],

    // Tag-based thresholds (specific endpoints)
    'http_req_duration{name:homepage}': ['p(95)<500'],

    // Abort test if threshold breached
    http_req_duration: [{ threshold: 'p(99)<3000', abortOnFail: true }],
  },
};
```

## Custom Metrics

```javascript
import { Counter, Gauge, Rate, Trend } from 'k6/metrics';

const myErrors = new Counter('my_errors');
const activeUsers = new Gauge('active_users');
const successRate = new Rate('success_rate');
const reqDuration = new Trend('req_duration', true); // true = display in ms

export default function () {
  const res = http.get(url);
  if (res.status !== 200) myErrors.add(1);
  successRate.add(res.status === 200);
  reqDuration.add(res.timings.duration);
}
```

## Scenarios and Executors

See `references/scenarios-executors.md` for full reference.

```javascript
export const options = {
  scenarios: {
    // Constant VUs
    steady_load: {
      executor: 'constant-vus',
      vus: 50,
      duration: '5m',
    },
    // Ramping VUs (most common)
    ramp_up: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '2m', target: 100 },
        { duration: '5m', target: 100 },
        { duration: '2m', target: 0 },
      ],
    },
    // Constant arrival rate (requests per second)
    constant_rps: {
      executor: 'constant-arrival-rate',
      rate: 100,             // 100 iterations/sec
      timeUnit: '1s',
      duration: '5m',
      preAllocatedVUs: 50,
      maxVUs: 200,
    },
    // Per-VU iterations
    per_vu: {
      executor: 'per-vu-iterations',
      vus: 10,
      iterations: 100,
    },
  },
};
```

## Test Types

See `references/test-types.md` for full examples.

| Type | Purpose | Load Pattern |
|------|---------|-------------|
| **Smoke** | Verify script works, minimal load | 1-2 VUs, short duration |
| **Load** | Normal expected load | Ramp up → steady → ramp down |
| **Stress** | Beyond normal capacity | Increasing stages until breaking |
| **Spike** | Sudden traffic surge | Instant spike then drop |
| **Soak** | Extended duration for memory leaks | Moderate load, hours-long |
| **Breakpoint** | Find system limits | Continuously increasing load |

## Environment Variables and CLI Flags

```bash
# Pass variables to script
k6 run -e MY_VAR=value script.js     # access as __ENV.MY_VAR
k6 run --env API_URL=https://api.example.com script.js

# Override options
k6 run --vus 50 --duration 60s script.js
k6 run --iterations 1000 script.js
k6 run --stage 30s:10,1m:50,30s:0 script.js   # ramping stages

# Output formats
k6 run --out json=result.json script.js
k6 run --out csv=result.csv script.js
k6 run --out influxdb=http://localhost:8086/k6 script.js
k6 run --out statsd script.js
```

## Groups and Tags

```javascript
import { group } from 'k6';

export default function () {
  group('homepage', () => {
    const res = http.get('/');
    check(res, { 'status 200': (r) => r.status === 200 });
  });

  group('login flow', () => {
    group('load login page', () => {
      http.get('/login');
    });
    group('submit credentials', () => {
      http.post('/login', { user: 'test', pass: 'test' });
    });
  });
}

// Custom tags on requests
http.get(url, { tags: { name: 'homepage', version: 'v2' } });
```

## WebSocket

```javascript
import ws from 'k6/ws';
import { check } from 'k6';

export default function () {
  const url = 'ws://echo.websocket.org';
  const res = ws.connect(url, {}, function (socket) {
    socket.on('open', () => {
      socket.send('Hello!');
      socket.setInterval(() => socket.ping(), 10000);
    });
    socket.on('message', (data) => {
      check(data, { 'message received': (d) => d.length > 0 });
    });
    socket.on('error', (e) => console.error(e.error()));
    socket.setTimeout(() => socket.close(), 30000);
  });
  check(res, { 'status 101': (r) => r.status === 101 });
}
```

## Browser Testing

```javascript
import { browser } from 'k6/browser';
import { check } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';

export const options = {
  scenarios: {
    ui: {
      executor: 'shared-iterations',
      options: { browser: { type: 'chromium' } },
    },
  },
};

export default async function () {
  const page = await browser.newPage();
  try {
    await page.goto('https://test.k6.io/my_messages.php');
    await page.locator('input[name="login"]').type('admin');
    await page.locator('input[name="password"]').type('123');
    await Promise.all([
      page.waitForNavigation(),
      page.locator('input[type="submit"]').click(),
    ]);
    check(page, { 'header': p => p.locator('h2').textContent() == 'Welcome, admin!' });
  } finally {
    await page.close();
  }
}
```

## Modules and Imports

```javascript
// Built-in modules
import http from 'k6/http';
import { check, group, sleep, fail } from 'k6';
import { Counter, Gauge, Rate, Trend } from 'k6/metrics';
import { SharedArray } from 'k6/data';
import { scenario, vu } from 'k6/execution';
import ws from 'k6/ws';
import grpc from 'k6/net/grpc';
import { browser } from 'k6/browser';
import crypto from 'k6/crypto';
import encoding from 'k6/encoding';
import { htmlReport } from 'https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js';

// jslib utilities
import { uuidv4 } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';
import { randomItem, randomIntBetween } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';
```

## SharedArray (efficient data loading)

```javascript
import { SharedArray } from 'k6/data';
import papaparse from 'https://jslib.k6.io/papaparse/5.1.1/index.js';

// Load CSV once, shared across all VUs
const users = new SharedArray('users', function () {
  return papaparse.parse(open('./users.csv'), { header: true }).data;
});

// Load JSON
const data = new SharedArray('data', function () {
  return JSON.parse(open('./data.json'));
});

export default function () {
  const user = users[Math.floor(Math.random() * users.length)];
  http.post('/login', { username: user.username, password: user.password });
}
```

## k6 Cloud (Grafana Cloud k6)

```javascript
export const options = {
  cloud: {
    projectID: 123456,
    name: 'My Load Test',
    note: 'Release candidate',
    distribution: {
      distributionLabel1: { loadZone: 'amazon:us:ashburn', percent: 50 },
      distributionLabel2: { loadZone: 'amazon:eu:dublin', percent: 50 },
    },
  },
};
```

```bash
# Authenticate
k6 cloud login --token <your-token>

# Run in cloud
k6 cloud script.js

# Run locally but stream results to cloud
k6 run --out cloud script.js
```

## CLI Flags Summary

| Flag | Description |
|------|-------------|
| `--vus N` | Number of virtual users |
| `--duration Xs/Xm/Xh` | Test duration |
| `--iterations N` | Total iterations |
| `--stage Xm:N` | Add ramp stage |
| `--env KEY=value` | Environment variable |
| `--out FORMAT` | Output destination |
| `--quiet` | Suppress progress output |
| `--no-summary` | Skip end-of-test summary |
| `--summary-export FILE` | Export summary as JSON |
| `--http-debug` | Print HTTP request/response details |
| `--insecure-skip-tls-verify` | Skip TLS verification |
| `--tag KEY=VALUE` | Add test-wide tag |

## Key Built-in Metrics

| Metric | Type | Description |
|--------|------|-------------|
| `http_req_duration` | Trend | Total request time |
| `http_req_failed` | Rate | Failed request rate |
| `http_req_waiting` | Trend | Time to first byte (TTFB) |
| `http_req_connecting` | Trend | TCP connection time |
| `http_req_tls_handshaking` | Trend | TLS handshake time |
| `http_reqs` | Counter | Total HTTP requests |
| `vus` | Gauge | Current active VUs |
| `vus_max` | Gauge | Max VUs allocated |
| `iterations` | Counter | Total VU iterations |
| `iteration_duration` | Trend | Time to complete one iteration |
| `data_sent` | Counter | Data sent |
| `data_received` | Counter | Data received |
| `checks` | Rate | Check success rate |

## References

- [JavaScript API](references/javascript-api.md)
- [Test Types](references/test-types.md)
- [Scenarios & Executors](references/scenarios-executors.md)
- [Examples](references/examples.md)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.