Skip to content
Testing
Skill

/k6-performance

Performance and load testing skill using k6, covering load test scripts, thresholds, scenarios, checks, custom metrics, and results analysis.

From plugin
qaskills
24413 skills

Claude Code

$ npx -y skills add PramodDutta/qaskills --skill k6-performance --agent claude-code

SKILL.md

k6-performance.SKILL.md
name: k6-performance
description: Performance and load testing skill using k6, covering load test scripts, thresholds, scenarios, checks, custom metrics, and results analysis.
license: MIT
metadata:
  author: thetestingacademy
  version: 1.0.0
  source: https://qaskills.sh/skills/thetestingacademy/k6-performance

k6 Performance Testing Skill

You are an expert performance engineer specializing in k6 load testing. When the user asks you to write, review, or debug k6 performance tests, follow these detailed instructions.

Core Principles

1. **Test realistic scenarios** -- Model tests after actual user behavior patterns. 2. **Define clear thresholds** -- Every test must have pass/fail criteria defined upfront. 3. **Ramp up gradually** -- Never slam the system with full load instantly. 4. **Use checks extensively** -- Validate responses even under load. 5. **Monitor and correlate** -- Combine k6 metrics with server-side monitoring.

Project Structure

k6/
  scripts/
    smoke-test.js
    load-test.js
    stress-test.js
    spike-test.js
    soak-test.js
  scenarios/
    api-scenarios.js
    user-flows.js
  utils/
    helpers.js
    auth.js
    data-generators.js
  data/
    users.csv
    payloads.json
  thresholds/
    default-thresholds.js
  config/
    environments.js
  results/
    .gitkeep

Basic Load Test Script

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

// Custom metrics
const errorRate = new Rate('errors');
const loginDuration = new Trend('login_duration');
const requestCount = new Counter('total_requests');

export const options = {
  stages: [
    { duration: '2m', target: 10 },   // Ramp up to 10 users
    { duration: '5m', target: 10 },   // Stay at 10 users
    { duration: '2m', target: 50 },   // Ramp up to 50 users
    { duration: '5m', target: 50 },   // Stay at 50 users
    { duration: '2m', target: 0 },    // Ramp down
  ],
  thresholds: {
    http_req_duration: ['p(95)<500', 'p(99)<1000'],  // 95th percentile < 500ms
    http_req_failed: ['rate<0.01'],                     // Error rate < 1%
    errors: ['rate<0.05'],                              // Custom error rate < 5%
    login_duration: ['p(95)<800'],                      // Login 95th < 800ms
  },
};

const BASE_URL = __ENV.BASE_URL || 'http://localhost:3000';

export default function () {
  group('Homepage', () => {
    const response = http.get(`${BASE_URL}/`);

    check(response, {
      'homepage status is 200': (r) => r.status === 200,
      'homepage loads in < 2s': (r) => r.timings.duration < 2000,
      'homepage has correct title': (r) => r.body.includes('<title>'),
    });

    errorRate.add(response.status !== 200);
    requestCount.add(1);
  });

  sleep(1);

  group('Login', () => {
    const startTime = Date.now();

    const loginResponse = http.post(`${BASE_URL}/api/auth/login`, JSON.stringify({
      email: 'user@example.com',
      password: 'SecurePass123!',
    }), {
      headers: { 'Content-Type': 'application/json' },
    });

    loginDuration.add(Date.now() - startTime);

    check(loginResponse, {
      'login status is 200': (r) => r.status === 200,
      'login returns token': (r) => JSON.parse(r.body).token !== undefined,
    });

    errorRate.add(loginResponse.status !== 200);
    requestCount.add(1);
  });

  sleep(Math.random() * 3 + 1); // Random think time between 1-4 seconds
}

Test Types

Smoke Test

export const options = {
  vus: 1,
  duration: '1m',
  thresholds: {
    http_req_duration: ['p(99)<1500'],
    http_req_failed: ['rate<0.01'],
  },
};

// Quick validation that the system works under minimal load
export default function () {
  const response = http.get(`${BASE_URL}/api/health`);
  check(response, {
    'status is 200': (r) => r.status === 200,
  });
  sleep(1);
}

Load Test

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

Stress Test

export const options = {
  stages: [
    { duration: '2m', target: 100 },
    { duration: '5m', target: 100 },
    { duration: '2m', target: 200 },
    { duration: '5m', target: 200 },
    { duration: '2m', target: 300 },
    { duration: '5m', target: 300 },
    { duration: '2m', target: 400 },
    { duration: '5m', target: 400 },
    { duration: '10m', target: 0 },
  ],
  thresholds: {
    http_req_duration: ['p(95)<1000'],
    http_req_failed: ['rate<0.05'],
  },
};

Spike Test

export const options = {
  stages: [
    { duration: '1m', target: 10 },     // Normal load
    { duration: '10s', target: 500 },    // Spike!
    { duration: '3m', target: 500 },     // Stay at spike
    { duration: '10s', target: 10 },     // Recovery
    { duration: '3m', target: 10 },      // Observe recovery
    { duration: '1m', target: 0 },       // Ramp down
  ],
};

Soak Test

export const options = {
  stages: [
    { duration: '5m', target: 50 },     // Ramp up
    { duration: '4h', target: 50 },     // Sustained load for 4 hours
    { duration: '5m', target: 0 },      // Ramp down
  ],
  thresholds: {
    http_req_duration: ['p(95)<500'],
    http_req_failed: ['rate<0.01'],
  },
};

Scenarios (Advanced Configuration)

export const options = {
  scenarios: {
    browse_products: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '2m', target: 50 },
        { duration: '5m', target: 50 },
        { duration: '2m', target: 0 },
      ],
      gracefulRampDown: '30s',
      exec: 'browseProducts',
    },
    checkout_flow: {
      executor: 'constant-arrival-rate',
      rate: 10,          // 10 iterations per timeUnit
Read more
@pramoddutta
Ships withqaskills

QA Skills Directory QA Skills is a curated directory of testing-specific skills for AI coding agents (Claude Code, Cursor, Copilot, etc.).

Stars on GitHub

Momentum

stars in total
244
Star history of PramodDutta/qaskills on GitHub, a chart by star-history.com

Other skills on qaskills.

add-seed-skills

add-seed-skills

Use when adding or editing QA skills in seed-skills/ or getting them onto the live qaskills.sh catalog, e.g. "add N new skills",…

publish-seo-batch

publish-seo-batch

Use when publishing SEO blog articles to qaskills.sh, e.g. "publish today's articles", "daily SEO batch", "write 10 articles from…

ship-prod

ship-prod

Use when deploying qaskills.sh to production, verifying whether a deploy landed, or when a push to main did not show up on the…

api-testing-rest

api-testing-rest

Comprehensive RESTful API testing patterns covering HTTP methods, status codes, request/response validation, authentication,…

claude-code-qa

claude-code-qa

The complete QA skill for Claude Code — turn Claude into an expert QA engineer that picks the right test type, writes reliable…

cypress-e2e

cypress-e2e

End-to-end testing skill using Cypress for web applications, covering custom commands, network intercepts, fixtures, cy.session,…

More skills from other plugins.

api-review

api-review

Produce the "Playwright 1.xx API Review" artifact for a range of commits - the public API additions and the breaking or behavior…

@microsoft@microsoftInstall Skill
add-e2e-selectors

add-e2e-selectors

Add reliable @grafana/e2e-selectors to interactive elements and key containers in the Grafana frontend. Use when adding e2e…

grafana1d78k
@grafana@grafanaInstall Skill
promptfoo-evals

promptfoo-evals

Write, refine, run, and QA promptfoo evaluation suites: promptfooconfig.yaml, prompts, providers, vars, tests, assertions,…

@promptfoo@promptfooInstall Skill
deepeval

deepeval

DeepEval evaluation workflow for AI agents and LLM applications. TRIGGER when the user wants to evaluate or improve an AI agent,…

@confident-ai@confident-aiInstall Skill

Questions about k6-performance.

Which coding agents can use k6-performance?
k6-performance installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.