Skip to content
k6-load-test logo

k6 Load Testing Expert

k6-load-test

Эксперт k6 нагрузочного тестирования. Используй для performance testing, load scenarios и stress tests.

SKILL.md

Full skill instructions

k6 Load Testing Expert

Expert in performance testing with k6 framework.

Core k6 Principles

  • Virtual Users (VUs): Each VU runs the test script independently in parallel
  • Iterations vs Duration: Choose between iteration-based or time-based test execution
  • Stages: Gradually ramp up/​down load to simulate realistic traffic patterns
  • Thresholds: Define pass/​fail criteria for automated performance validation
  • Metrics: Focus on key performance indicators (response time, throughput, error rate)

Basic Test Script Structure

import http from 'k6/​http';
import { check, sleep } from 'k6';
import { Rate, Trend } from 'k6/​metrics';

// Custom metrics
const errorRate = new Rate('errors');
const customTrend = new Trend('custom_duration');

// Test configuration
export const options = {
  stages: [
    { duration: '2m', target: 10 },  // Ramp up to 10 users
    { duration: '5m', target: 10 },  // Stay at 10 users
    { duration: '2m', target: 20 },  // Ramp up to 20 users
    { duration: '5m', target: 20 },  // Stay at 20 users
    { duration: '2m', target: 0 },   // Ramp down to 0
  ],
  thresholds: {
    http_req_duration: ['p(95)<500'],  // 95% of requests under 500ms
    http_req_failed: ['rate<0.1'],     // Error rate under 10%
    errors: ['rate<0.1'],
  },
};

// Setup function (runs once before test)
export function setup() {
  // Prepare test data, authenticate, etc.
  const loginRes = http.post('https://api.example.com/​auth/​login', {
    email: '[email protected]',
    password: 'password123',
  });

  return { token: loginRes.json('token') };
}

// Main test function (runs for each VU)
export default function(data) {
  const params = {
    headers: {
      'Authorization': `Bearer ${data.token}`,
      'Content-Type': 'application/​json',
    },
  };

  const response = http.get('https://api.example.com/​users', params);

  // Verify response
  check(response, {
    'status is 200': (r) => r.status === 200,
    'response time < 500ms': (r) => r.timings.duration < 500,
    'response body contains users': (r) => r.body.includes('users'),
  });

  // Track custom metrics
  errorRate.add(response.status !== 200);
  customTrend.add(response.timings.duration);

  // Think time between requests
  sleep(Math.random() * 2 + 1); // 1-3 seconds
}

// Teardown function (runs once after test)
export function teardown(data) {
  // Cleanup operations
  console.log('Test completed');
}

Test Scenario Patterns

Load Test (Normal Traffic)

export const options = {
  stages: [
    { duration: '5m', target: 50 },   // Ramp up
    { duration: '30m', target: 50 },  // Steady state
    { duration: '5m', target: 0 },    // Ramp down
  ],
  thresholds: {
    http_req_duration: ['p(95)<200', 'p(99)<500'],
    http_req_failed: ['rate<0.01'],
  },
};

Stress Test (Beyond Normal Capacity)

export const options = {
  stages: [
    { duration: '2m', target: 100 },
    { duration: '5m', target: 100 },
    { duration: '2m', target: 200 },
    { duration: '5m', target: 200 },
    { duration: '2m', target: 300 },  // Beyond normal capacity
    { duration: '5m', target: 300 },
    { duration: '10m', target: 400 }, // Breaking point
    { duration: '2m', target: 0 },
  ],
};

Spike Test (Sudden Traffic Surge)

export const options = {
  stages: [
    { duration: '10s', target: 100 },  // Quick ramp-up
    { duration: '1m', target: 100 },   // Stay at peak
    { duration: '10s', target: 0 },    // Quick ramp-down
  ],
};

Soak Test (Extended Duration)

export const options = {
  stages: [
    { duration: '5m', target: 50 },
    { duration: '4h', target: 50 },   // Run for 4 hours
    { duration: '5m', target: 0 },
  ],
};

Breakpoint Test (Find Limits)

export const options = {
  executor: 'ramping-arrival-rate',
  stages: [
    { duration: '2m', target: 100 },
    { duration: '2m', target: 200 },
    { duration: '2m', target: 300 },
    { duration: '2m', target: 400 },
    { duration: '2m', target: 500 },
    // Continue until system breaks
  ],
};

Advanced Patterns

Data-Driven Testing

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

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

export default function() {
  // Random user from dataset
  const user = csvData[Math.floor(Math.random() * csvData.length)];

  const payload = JSON.stringify({
    username: user.username,
    password: user.password,
  });

  const response = http.post('https://api.example.com/​login', payload, {
    headers: { 'Content-Type': 'application/​json' },
  });

  check(response, {
    'login successful': (r) => r.status === 200,
    'token present': (r) => r.json('token') !== '',
  });
}

Session-Based Testing with Groups

import { group, sleep } from 'k6';
import http from 'k6/​http';

export default function() {
  let authToken;

  group('Authentication', function() {
    const loginRes = http.post('https://api.example.com/​auth/​login', {
      email: '[email protected]',
      password: 'password123',
    });

    check(loginRes, { 'login successful': (r) => r.status === 200 });
    authToken = loginRes.json('token');
  });

  const headers = { Authorization: `Bearer ${authToken}` };

  group('Browse Products', function() {
    const productsRes = http.get('https://api.example.com/​products', { headers });
    check(productsRes, { 'products loaded': (r) => r.status === 200 });

    const productId = productsRes.json('products')[0].id;
    const detailRes = http.get(`https://api.example.com/​products/​${productId}`, { headers });
    check(detailRes, { 'product detail loaded': (r) => r.status === 200 });
  });

  group('Add to Cart', function() {
    const cartRes = http.post('https://api.example.com/​cart',
      JSON.stringify({ productId: 1, quantity: 2 }),
      { headers: { ...headers, 'Content-Type': 'application/​json' } }
    );
    check(cartRes, { 'added to cart': (r) => r.status === 200 });
  });

  group('Checkout', function() {
    const checkoutRes = http.post('https://api.example.com/​checkout',
      JSON.stringify({ paymentMethod: 'card' }),
      { headers: { ...headers, 'Content-Type': 'application/​json' } }
    );
    check(checkoutRes, { 'checkout successful': (r) => r.status === 200 });
  });

  sleep(1);
}

Batch Requests

import http from 'k6/​http';

export default function() {
  const responses = http.batch([
    ['GET', 'https://api.example.com/​users'],
    ['GET', 'https://api.example.com/​products'],
    ['GET', 'https://api.example.com/​orders'],
    ['POST', 'https://api.example.com/​events', JSON.stringify({ event: 'page_view' }), {
      headers: { 'Content-Type': 'application/​json' },
    }],
  ]);

  check(responses[0], { 'users status 200': (r) => r.status === 200 });
  check(responses[1], { 'products status 200': (r) => r.status === 200 });
  check(responses[2], { 'orders status 200': (r) => r.status === 200 });
}

Custom Metrics

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

// Define custom metrics
const pageViews = new Counter('page_views');
const activeUsers = new Gauge('active_users');
const errorRate = new Rate('error_rate');
const responseTrend = new Trend('response_trend');

export default function() {
  const response = http.get('https://api.example.com/​page');

  // Record metrics
  pageViews.add(1);
  activeUsers.add(__VU);  // Current VU count
  errorRate.add(response.status !== 200);
  responseTrend.add(response.timings.duration);

  // Tags for segmentation
  pageViews.add(1, { page: 'home', version: 'v2' });
}

Environment Configuration

Command Line Options

# Basic run
k6 run script.js

# Specify VUs and duration
k6 run --vus 50 --duration 10m script.js

# Environment variables
k6 run --env BASE_URL=https://staging.api.com --env API_KEY=xxx script.js

# Output to different backends
k6 run --out influxdb=http://localhost:8086/​k6 script.js
k6 run --out json=results.json script.js
k6 run --out csv=results.csv script.js

# Cloud execution
k6 cloud script.js

# Run with config file
k6 run --config config.json script.js

Environment Variables in Script

const BASE_URL = __ENV.BASE_URL || 'https://api.example.com';
const API_KEY = __ENV.API_KEY || 'default-key';
const ENVIRONMENT = __ENV.ENV || 'staging';

export default function() {
  const response = http.get(`${BASE_URL}/​endpoint`, {
    headers: { 'X-API-Key': API_KEY },
  });
}

CI/​CD Integration

GitHub Actions

name: Load Test

on:
  push:
    branches: [main]
  schedule:
    - cron: '0 2 * * *'  # Daily at 2 AM

jobs:
  load-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/​checkout@v4

      - name: Install k6
        run: |
          curl -L https://github.com/​grafana/​k6/​releases/​download/​v0.47.0/​k6-v0.47.0-linux-amd64.tar.gz | tar xvz
          sudo mv k6-v0.47.0-linux-amd64/​k6 /​usr/​local/​bin/

      - name: Run load test
        run: k6 run --env BASE_URL=${{ secrets.API_URL }} tests/​load-test.js

      - name: Upload results
        uses: actions/​upload-artifact@v3
        with:
          name: k6-results
          path: results.json

Debugging and Analysis

import { textSummary } from 'https://jslib.k6.io/​k6-summary/​0.0.1/​index.js';

// Custom summary handler
export function handleSummary(data) {
  return {
    'stdout': textSummary(data, { indent: ' ', enableColors: true }),
    'summary.json': JSON.stringify(data),
  };
}

export default function() {
  const response = http.get('https://api.example.com/​data');

  // Detailed debugging on failure
  if (!check(response, { 'status is 200': (r) => r.status === 200 })) {
    console.error(`Request failed: ${response.status}`);
    console.error(`Response body: ${response.body.substring(0, 500)}`);
    console.error(`Request URL: ${response.request.url}`);
  }

  // Log slow requests
  if (response.timings.duration > 1000) {
    console.warn(`Slow request: ${response.timings.duration}ms - ${response.request.url}`);
  }
}

Key Metrics Reference

MetricDescriptionTypical Threshold
http_req_durationResponse timep(95)<500ms
http_req_failedFailed request raterate<0.01
http_reqsRequests per secondN/​A (informational)
http_req_waitingTime to first bytep(95)<200ms
vusActive virtual usersN/​A
iterationsCompleted iterationsN/​A

Лучшие практики

  1. Realistic think time — добавляйте sleep() между запросами
  2. Gradual ramp-up — избегайте мгновенной нагрузки
  3. SharedArray for data — экономит память при больших датасетах
  4. Meaningful thresholds — определяйте SLO заранее
  5. Tags for segmentation — группируйте метрики по endpoint/​feature
  6. Monitor load generator — убедитесь, что k6 не bottleneck

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View