performance-testing

Load testing with k6/Artillery, response time thresholds, memory leak detection, N+1 query detection, and CI integration.

422 stars

Best use case

performance-testing is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Load testing with k6/Artillery, response time thresholds, memory leak detection, N+1 query detection, and CI integration.

Teams using performance-testing should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/performance-testing/SKILL.md --create-dirs "https://raw.githubusercontent.com/vibeeval/vibecosystem/main/skills/performance-testing/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/performance-testing/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How performance-testing Compares

Feature / Agentperformance-testingStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Load testing with k6/Artillery, response time thresholds, memory leak detection, N+1 query detection, and CI integration.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# Performance Testing

## k6 Script Patterns

### Basic scenario with stages
```javascript
// k6 run load-test.js
import http from 'k6/http'
import { check, sleep } from 'k6'

export const options = {
  stages: [
    { duration: '30s', target: 10 },   // ramp up
    { duration: '1m',  target: 50 },   // hold load
    { duration: '30s', target: 0 },    // ramp down
  ],
  thresholds: {
    http_req_duration: ['p(95)<200', 'p(99)<500'],
    http_req_failed:   ['rate<0.01'],   // < 1% error rate
  },
}

export default function () {
  const res = http.get('https://api.example.com/users')
  check(res, {
    'status is 200':       (r) => r.status === 200,
    'response time < 200ms': (r) => r.timings.duration < 200,
  })
  sleep(1)
}
```

### POST with auth
```javascript
export default function () {
  const payload = JSON.stringify({ email: 'test@example.com', password: 'secret' })
  const headers = { 'Content-Type': 'application/json' }
  const res = http.post(`${BASE_URL}/auth/login`, payload, { headers })
  const token = res.json('token')

  http.get(`${BASE_URL}/profile`, {
    headers: { Authorization: `Bearer ${token}` },
  })
}
```

## Load Test Types

| Type | Duration | Target VU | Purpose |
|------|----------|-----------|---------|
| Smoke | 1 min | 1-5 | Verify script works, no regressions |
| Load | 30 min | expected peak | Normal production conditions |
| Stress | 60 min | 2-3x peak | Find breaking point |
| Spike | 2 min | 10x peak → 0 | Sudden traffic burst behavior |
| Soak | 4-8 hours | 80% peak | Memory leaks, degradation over time |

## Threshold Definitions

```javascript
export const options = {
  thresholds: {
    // Response time
    http_req_duration: ['p(95)<200', 'p(99)<500', 'avg<100'],

    // Error rate
    http_req_failed: ['rate<0.01'],   // < 1%

    // Custom metric for specific endpoint
    'http_req_duration{name:login}': ['p(95)<300'],

    // Checks pass rate
    checks: ['rate>0.99'],
  },
}
```

## CI Integration (GitHub Actions + k6)

```yaml
# .github/workflows/perf.yml
name: Performance Tests
on:
  pull_request:
    branches: [main]

jobs:
  k6:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run k6 smoke test
        uses: grafana/k6-action@v0.3.1
        with:
          filename: tests/perf/smoke.js
          flags: --out json=results.json
      - name: Upload results
        uses: actions/upload-artifact@v4
        with:
          name: k6-results
          path: results.json
```

## Memory Leak Detection (Node.js)

### Heap snapshot approach
```bash
# Start with --inspect
node --inspect --expose-gc server.js

# In Chrome DevTools → Memory → Take heap snapshot
# Run load, take another snapshot
# Compare: growing retained objects = leak
```

### Programmatic detection
```javascript
import v8 from 'v8'

function checkHeap(label) {
  const stats = v8.getHeapStatistics()
  console.log(`[${label}] Heap used: ${Math.round(stats.used_heap_size / 1024 / 1024)}MB`)
}

setInterval(() => checkHeap('monitor'), 30_000)
```

### Common leak patterns to watch
```javascript
// BAD: event listener never removed
emitter.on('data', handler)   // grows on every request

// GOOD: cleanup in teardown
emitter.on('data', handler)
return () => emitter.off('data', handler)

// BAD: unbounded cache
const cache = {}
cache[userId] = data   // never evicted

// GOOD: bounded cache
import LRU from 'lru-cache'
const cache = new LRU({ max: 1000, ttl: 1000 * 60 * 5 })
```

## N+1 Query Detection

### pg_stat_statements (PostgreSQL)
```sql
-- Enable extension
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

-- Find repetitive queries during a load test window
SELECT
  query,
  calls,
  mean_exec_time,
  total_exec_time
FROM pg_stat_statements
WHERE calls > 100
ORDER BY calls DESC
LIMIT 20;
```

### Query logging (development)
```javascript
// Prisma: log all queries
const prisma = new PrismaClient({
  log: ['query'],
})

// Detect N+1: same query fired N times in a request
// Fix: use include/select or DataLoader
```

### DataLoader pattern (N+1 fix)
```javascript
import DataLoader from 'dataloader'

const userLoader = new DataLoader(async (ids) => {
  const users = await db.user.findMany({ where: { id: { in: ids } } })
  return ids.map(id => users.find(u => u.id === id))
})

// In resolver — batches automatically
const user = await userLoader.load(post.authorId)
```

## Web Vitals / Lighthouse CI

```yaml
# .github/workflows/lhci.yml
- name: Lighthouse CI
  run: |
    npm install -g @lhci/cli
    lhci autorun
  env:
    LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
```

```json
// lighthouserc.json
{
  "ci": {
    "assert": {
      "assertions": {
        "categories:performance": ["error", { "minScore": 0.8 }],
        "first-contentful-paint": ["error", { "maxNumericValue": 2000 }],
        "largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
        "cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }]
      }
    }
  }
}
```

## Trend Tracking

Store k6 results to Grafana/InfluxDB for trend visualization:

```bash
k6 run --out influxdb=http://localhost:8086/k6 load-test.js
```

Or export JSON and compare baselines:

```bash
k6 run --out json=results-$(git rev-parse --short HEAD).json load-test.js
```

Related Skills

python-testing

422
from vibeeval/vibecosystem

Python testing strategies using pytest, TDD methodology, fixtures, mocking, parametrization, and coverage requirements.

property-based-testing

422
from vibeeval/vibecosystem

Property-based testing (PBT) patterns with fast-check (JS/TS), Hypothesis (Python), and gopter (Go). Generate random inputs, define invariants, shrink failures to minimal cases. Adapted from Trail of Bits. Use when testing pure functions, parsers, serializers, state machines, or any code where example-based tests miss edge cases.

load-testing-patterns

422
from vibeeval/vibecosystem

k6 script templates, load profiles, response time thresholds, SLO validation, and performance testing strategies.

golang-testing

422
from vibeeval/vibecosystem

Go testing patterns including table-driven tests, subtests, benchmarks, fuzzing, and test coverage. Follows TDD methodology with idiomatic Go practices.

contract-testing-patterns

422
from vibeeval/vibecosystem

Pact consumer-driven contracts, provider verification, schema evolution

accessibility-testing

422
from vibeeval/vibecosystem

axe-core integration, WCAG 2.2 AA checklist, keyboard navigation testing, screen reader testing, and ARIA pattern validation.

workflow-router

422
from vibeeval/vibecosystem

Goal-based workflow orchestration - routes tasks to specialist agents based on user goals

wiring

422
from vibeeval/vibecosystem

Wiring Verification

websocket-patterns

422
from vibeeval/vibecosystem

Connection management, room patterns, reconnection strategies, message buffering, and binary protocol design.

visual-verdict

422
from vibeeval/vibecosystem

Screenshot comparison QA for frontend development. Takes a screenshot of the current implementation, scores it across multiple visual dimensions, and returns a structured PASS/REVISE/FAIL verdict with concrete fixes. Use when implementing UI from a design reference or verifying visual correctness.

verification-loop

422
from vibeeval/vibecosystem

Comprehensive verification system covering build, types, lint, tests, security, and diff review before a PR.

vector-db-patterns

422
from vibeeval/vibecosystem

Embedding strategies, ANN algorithms, hybrid search, RAG chunking strategies, and reranking for semantic search and retrieval.