
Performance Testing
- 12 installs
- 213 repo stars
- Updated August 4, 2026
- yonatangross/orchestkit
Helps with testing & qa tasks.
About
performance-testing is a Claude Code skill for testing & qa. It helps developers move faster with AI-assisted coding.
- performance-testing
- Testing & QA
- AI-coding skill
Performance Testing by the numbers
- 12 all-time installs (skills.sh)
- Ranked #1,527 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/yonatangross/orchestkit --skill performance-testingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 12 |
|---|---|
| repo stars | ★ 213 |
| Last updated | August 4, 2026 |
| Repository | yonatangross/orchestkit ↗ |
What it does
Helps with testing & qa tasks.
Files
Performance Testing
Validate system behavior under load.
k6 Load Test (JavaScript)
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '30s', target: 20 }, // Ramp up
{ duration: '1m', target: 20 }, // Steady
{ duration: '30s', target: 0 }, // Ramp down
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95% under 500ms
http_req_failed: ['rate<0.01'], // <1% errors
},
};
export default function () {
const res = http.get('http://localhost:8500/api/health');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 200ms': (r) => r.timings.duration < 200,
});
sleep(1);
}Locust Load Test (Python)
from locust import HttpUser, task, between
class APIUser(HttpUser):
wait_time = between(1, 3)
@task(3)
def get_analyses(self):
self.client.get("/api/analyses")
@task(1)
def create_analysis(self):
self.client.post(
"/api/analyses",
json={"url": "https://example.com"}
)
def on_start(self):
"""Login before tasks."""
self.client.post("/api/auth/login", json={
"email": "test@example.com",
"password": "password"
})Test Types
Load Test
// Normal expected load
export const options = {
vus: 50, // Virtual users
duration: '5m', // Duration
};Stress Test
// Find breaking point
export const options = {
stages: [
{ duration: '2m', target: 100 },
{ duration: '2m', target: 200 },
{ duration: '2m', target: 300 },
{ duration: '2m', target: 400 },
],
};Spike Test
// Sudden traffic surge
export const options = {
stages: [
{ duration: '10s', target: 10 },
{ duration: '1s', target: 1000 }, // Spike!
{ duration: '3m', target: 1000 },
{ duration: '10s', target: 10 },
],
};Soak Test
// Sustained load (memory leaks)
export const options = {
vus: 50,
duration: '4h',
};Metrics to Track
import { Trend, Counter, Rate } from 'k6/metrics';
const responseTime = new Trend('response_time');
const errors = new Counter('errors');
const successRate = new Rate('success_rate');
export default function () {
const start = Date.now();
const res = http.get('http://localhost:8500/api/data');
responseTime.add(Date.now() - start);
if (res.status !== 200) {
errors.add(1);
successRate.add(false);
} else {
successRate.add(true);
}
}CI Integration
# GitHub Actions
- name: Run k6 load test
run: |
k6 run --out json=results.json tests/load/api.js
- name: Check thresholds
run: |
if [ $(jq '.thresholds | .[] | select(.ok == false)' results.json | wc -l) -gt 0 ]; then
exit 1
fiKey Decisions
| Decision | Recommendation |
|---|---|
| Tool | k6 (JS), Locust (Python) |
| Load profile | Start with expected traffic |
| Thresholds | p95 < 500ms, errors < 1% |
| Duration | 5-10 min for load, 4h+ for soak |
Common Mistakes
- Testing against production without protection
- No warmup period
- Unrealistic load profiles
- Missing error rate thresholds
Related Skills
observability-monitoring- Metrics collectionperformance-optimization- Fixing bottleneckse2e-testing- Functional validation
Capability Details
load-testing
Keywords: load test, concurrent users, k6, Locust, ramp up Solves:
- Simulate concurrent user load
- Configure ramp-up patterns
- Test system under expected load
stress-testing
Keywords: stress test, breaking point, peak load, overload Solves:
- Find system breaking points
- Test beyond expected capacity
- Identify failure modes under stress
latency-measurement
Keywords: latency, response time, p95, p99, percentile Solves:
- Measure response time percentiles
- Track latency distribution
- Set latency SLO thresholds
throughput-testing
Keywords: throughput, requests per second, RPS, TPS Solves:
- Measure maximum throughput
- Test transactions per second
- Verify capacity requirements
bottleneck-identification
Keywords: bottleneck, profiling, hot path, performance issue Solves:
- Identify performance bottlenecks
- Profile critical code paths
- Diagnose slow operations
Performance Testing Checklist
Test Planning
- [ ] Define performance goals
- [ ] Identify critical paths
- [ ] Determine test scenarios
- [ ] Set baseline metrics
Test Setup
- [ ] Production-like environment
- [ ] Realistic test data
- [ ] Proper warm-up period
- [ ] Isolated test environment
Metrics
- [ ] Response time (p50, p95, p99)
- [ ] Throughput (requests/sec)
- [ ] Error rate
- [ ] Resource utilization
Load Patterns
- [ ] Steady state
- [ ] Ramp up
- [ ] Spike testing
- [ ] Soak testing
Analysis
- [ ] Identify bottlenecks
- [ ] Compare to baseline
- [ ] Document findings
- [ ] Create action items
k6 Load Testing Patterns
Common patterns for effective performance testing with k6.
Implementation
Staged Ramp-Up Pattern
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '1m', target: 50 }, // Ramp up to 50 users
{ duration: '3m', target: 50 }, // Stay at 50 users
{ duration: '1m', target: 100 }, // Ramp to 100 users
{ duration: '3m', target: 100 }, // Stay at 100 users
{ duration: '2m', target: 0 }, // Ramp down
],
thresholds: {
http_req_duration: ['p(95)<500', 'p(99)<1000'],
http_req_failed: ['rate<0.01'],
checks: ['rate>0.99'],
},
};
export default function () {
const res = http.get('http://localhost:8000/api/health');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 200ms': (r) => r.timings.duration < 200,
'body contains status': (r) => r.body.includes('ok'),
});
sleep(Math.random() * 2 + 1); // 1-3 second think time
}Authenticated Requests Pattern
import http from 'k6/http';
import { check } from 'k6';
export function setup() {
const loginRes = http.post('http://localhost:8000/api/auth/login', {
email: 'loadtest@example.com',
password: 'testpassword',
});
return { token: loginRes.json('access_token') };
}
export default function (data) {
const params = {
headers: { Authorization: `Bearer ${data.token}` },
};
const res = http.get('http://localhost:8000/api/protected', params);
check(res, { 'authenticated request ok': (r) => r.status === 200 });
}Test Types Summary
| Type | Duration | VUs | Purpose |
|---|---|---|---|
| Smoke | 1 min | 1-5 | Verify script works |
| Load | 5-10 min | Expected | Normal traffic |
| Stress | 10-20 min | 2-3x expected | Find limits |
| Soak | 4-12 hours | Normal | Memory leaks |
Checklist
- [ ] Define realistic thresholds (p95, p99, error rate)
- [ ] Include proper ramp-up period (avoid cold start)
- [ ] Add think time between requests (sleep)
- [ ] Use checks for functional validation
- [ ] Externalize configuration (stages, VUs)
- [ ] Run smoke test before full load test
// Template: k6 Load Test Script
// Usage: Customize BASE_URL, endpoints, and thresholds for your API
import http from 'k6/http';
import { check, sleep, group } from 'k6';
import { Trend, Counter, Rate } from 'k6/metrics';
// ============================================================================
// CONFIGURATION
// ============================================================================
const BASE_URL = __ENV.BASE_URL || 'http://localhost:8000';
export const options = {
// Test scenarios
scenarios: {
// Smoke test: Quick validation
smoke: {
executor: 'constant-vus',
vus: 1,
duration: '30s',
tags: { test_type: 'smoke' },
},
// Load test: Normal expected traffic
load: {
executor: 'ramping-vus',
startVUs: 0,
stages: [
{ duration: '1m', target: 50 }, // Ramp up
{ duration: '3m', target: 50 }, // Steady state
{ duration: '1m', target: 0 }, // Ramp down
],
startTime: '30s', // Start after smoke
tags: { test_type: 'load' },
},
},
// Performance thresholds
thresholds: {
http_req_duration: [
'p(50)<200', // 50% of requests under 200ms
'p(95)<500', // 95% of requests under 500ms
'p(99)<1000', // 99% of requests under 1s
],
http_req_failed: ['rate<0.01'], // Less than 1% failures
checks: ['rate>0.99'], // 99% of checks pass
'api_response_time': ['p(95)<400'],
},
};
// ============================================================================
// CUSTOM METRICS
// ============================================================================
const apiResponseTime = new Trend('api_response_time');
const apiErrors = new Counter('api_errors');
const apiSuccessRate = new Rate('api_success_rate');
// ============================================================================
// SETUP (runs once before all VUs)
// ============================================================================
export function setup() {
console.log(`Testing against: ${BASE_URL}`);
// Optional: Authenticate and get token
const loginRes = http.post(`${BASE_URL}/api/auth/login`, JSON.stringify({
email: __ENV.TEST_USER || 'loadtest@example.com',
password: __ENV.TEST_PASSWORD || 'testpassword',
}), {
headers: { 'Content-Type': 'application/json' },
});
const token = loginRes.json('access_token');
if (!token) {
console.warn('Authentication failed, running unauthenticated tests');
}
return { token };
}
// ============================================================================
// MAIN TEST SCENARIO
// ============================================================================
export default function (data) {
const headers = {
'Content-Type': 'application/json',
...(data.token && { Authorization: `Bearer ${data.token}` }),
};
// Group 1: Health Check
group('Health Check', () => {
const res = http.get(`${BASE_URL}/api/health`);
check(res, {
'health status 200': (r) => r.status === 200,
'health response < 100ms': (r) => r.timings.duration < 100,
});
});
// Group 2: Read Operations (70% of traffic)
group('Read Operations', () => {
// TODO: Replace with your actual endpoints
const endpoints = [
'/api/users',
'/api/items',
'/api/dashboard',
];
const endpoint = endpoints[Math.floor(Math.random() * endpoints.length)];
const res = http.get(`${BASE_URL}${endpoint}`, { headers });
const success = check(res, {
'read status 200': (r) => r.status === 200,
'read has body': (r) => r.body && r.body.length > 0,
});
apiResponseTime.add(res.timings.duration);
apiSuccessRate.add(success);
if (!success) apiErrors.add(1);
});
// Group 3: Write Operations (30% of traffic)
if (Math.random() < 0.3) {
group('Write Operations', () => {
// TODO: Replace with your actual create endpoint
const payload = JSON.stringify({
name: `LoadTest-${Date.now()}`,
value: Math.random() * 100,
});
const res = http.post(`${BASE_URL}/api/items`, payload, { headers });
const success = check(res, {
'create status 201': (r) => r.status === 201,
'create returns id': (r) => r.json('id') !== undefined,
});
apiResponseTime.add(res.timings.duration);
apiSuccessRate.add(success);
if (!success) apiErrors.add(1);
});
}
// Think time: simulate real user behavior
sleep(Math.random() * 2 + 1); // 1-3 seconds
}
// ============================================================================
// TEARDOWN (runs once after all VUs complete)
// ============================================================================
export function teardown(data) {
console.log('Load test complete');
// Optional: Cleanup test data created during the run
}
// ============================================================================
// USAGE
// ============================================================================
// Run smoke test only:
// k6 run --env BASE_URL=http://localhost:8000 script.js --scenario smoke
// Run full load test:
// k6 run --env BASE_URL=http://localhost:8000 script.js
// Export results:
// k6 run --out json=results.json script.js
// k6 run --out influxdb=http://localhost:8086/k6 script.js