Benchmark System Performance Accurately
Designs performance benchmarks: Artillery load tests, database/API latency measurement, and system resource monitoring.
Maintainer of this project? Claim this page to edit the listing.
1.0.0Add to Favorites
Why it matters
Optimize your system's performance by designing and executing comprehensive benchmark strategies. This asset analyzes load testing, database interactions, and API performance to identify bottlenecks and provide actionable optimization recommendations.
Outcomes
What it gets done
Design and implement statistically valid performance benchmark strategies.
Execute load tests using tools like Artillery for API performance.
Conduct database performance testing with detailed metric analysis.
Analyze results to provide actionable optimization recommendations.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/vb-performance-benchmark | bash Overview
Performance Benchmark Expert
Provides expert performance benchmarking guidance covering load testing, database/API latency measurement, and system resource monitoring. Use when designing a load test strategy, benchmarking latency and throughput, or establishing a baseline-to-optimization workflow.
What it does
Provides expert guidance for performance benchmarking, load testing, and system performance analysis - designing statistically valid benchmark strategies, implementing tests across databases/APIs, and producing actionable optimization recommendations.
When to use - and when NOT to
Use this skill when designing a load test strategy, benchmarking database or API latency and throughput, monitoring system resources during a benchmark run, or establishing a baseline-to-optimization workflow with regression detection. Not a fit for functional/correctness testing unrelated to performance, or for production benchmarking without proper safeguards.
Inputs and outputs
Core principles cover statistical validity (multiple iterations, warm-up periods to account for JIT/caching, reporting P50/P95/P99 alongside averages), realistic test conditions (mirroring production, realistic data volumes, synthetic and real-world workloads), and comprehensive metrics (latency, throughput, resource utilization, error rates, system-level CPU/memory/I/O/network, and user-experience metrics like TTFB).
Provides an Artillery YAML load test configuration with warm-up/sustained/peak load phases, a weighted scenario chaining a list request (capturing a user ID) into a detail request with status code and property assertions. Provides a Python DatabaseBenchmark class executing a query with a warm-up phase followed by timed iterations, computing average/P50/P95/P99 latency and error rate, plus a concurrent load test using ThreadPoolExecutor to drive requests for a fixed duration.
Provides a JavaScript APIBenchmark class using axios and perf_hooks, running warm-up iterations then concurrency-controlled benchmark iterations, tracking per-request duration/status/response size/memory delta, and computing aggregate statistics (error rate, average/P50/P95/P99 latency, throughput in requests/sec, average response size). Provides a bash system monitoring script sampling CPU usage, memory usage/percentage, disk I/O, network I/O, and load average at a configurable interval into a timestamped CSV file.
Best practices cover test environment setup (isolating the benchmark environment, dedicated hardware/containers with resource limits, disabling background processes, documenting environment specs), data collection/analysis (baseline measurements before optimization, correlation analysis for bottlenecks, automated regression detection, historical trend storage), and pitfalls to avoid (relying solely on averages instead of percentiles, including cold-start measurements in final results, ignoring resource constraints, benchmarking production without safeguards). Defines a six-step optimization workflow: establish baseline, identify bottlenecks via profiling, make targeted optimizations, re-run benchmarks to validate, monitor for regressions, and document changes with their performance impact.
Integrations
Uses Artillery for HTTP load testing, psycopg2 with ThreadPoolExecutor for PostgreSQL benchmarking, axios/perf_hooks for API benchmarking in Node.js, and standard Linux tools (top, free, iostat, /proc/net/dev, uptime) for system resource monitoring.
Who it's for
Performance and platform engineers designing or running benchmarks for APIs, databases, or systems who need statistically valid test implementations and concrete metrics collection rather than ad hoc single-run timing measurements.
def execute_query(self, query, params=None, iterations=100):
latencies = []
Source README
Performance Benchmark Expert
You are an expert in performance benchmarking, load testing, and system performance analysis. You specialize in designing comprehensive benchmark strategies, implementing performance tests, analyzing results, and providing actionable optimization recommendations across various technologies and platforms.
Core Benchmarking Principles
Statistical Validity
- Always run multiple iterations and calculate statistical significance
- Use proper warm-up periods to account for JIT compilation and caching
- Report percentiles (P50, P95, P99) alongside averages
- Account for system variance and external factors
Realistic Test Conditions
- Mirror production environments as closely as possible
- Use realistic data volumes and patterns
- Test under various load conditions and scenarios
- Include both synthetic and real-world workloads
Comprehensive Metrics
- Measure latency, throughput, resource utilization, and error rates
- Monitor system-level metrics (CPU, memory, I/O, network)
- Track application-specific KPIs
- Consider user experience metrics like Time to First Byte (TTFB)
Benchmark Implementation Patterns
Load Testing with Artillery
config:
target: 'https://api.example.com'
phases:
- duration: 60
arrivalRate: 10
name: "Warm up"
- duration: 300
arrivalRate: 50
name: "Sustained load"
- duration: 120
arrivalRate: 100
name: "Peak load"
processor: "./custom-functions.js"
variables:
endpoint: "/api/users"
scenarios:
- name: "User API Benchmark"
weight: 70
flow:
- get:
url: "{{ endpoint }}"
headers:
Authorization: "Bearer {{ $randomString() }}"
capture:
- json: "$.data[0].id"
as: "userId"
- think: 2
- get:
url: "/api/users/{{ userId }}"
expect:
- statusCode: 200
- hasProperty: "data.email"
Database Performance Testing
import time
import statistics
import psycopg2
from concurrent.futures import ThreadPoolExecutor, as_completed
class DatabaseBenchmark:
def __init__(self, connection_string, num_connections=10):
self.connection_string = connection_string
self.num_connections = num_connections
def execute_query(self, query, params=None, iterations=100):
"""Execute query with proper timing and statistics"""
latencies = []
errors = 0
with psycopg2.connect(self.connection_string) as conn:
cursor = conn.cursor()
# Warm-up
for _ in range(10):
try:
cursor.execute(query, params)
cursor.fetchall()
except Exception:
pass
# Actual benchmark
for _ in range(iterations):
start_time = time.perf_counter()
try:
cursor.execute(query, params)
results = cursor.fetchall()
latency = (time.perf_counter() - start_time) * 1000
latencies.append(latency)
except Exception as e:
errors += 1
return {
'avg_latency_ms': statistics.mean(latencies) if latencies else 0,
'p50_latency_ms': statistics.median(latencies) if latencies else 0,
'p95_latency_ms': self._percentile(latencies, 95) if latencies else 0,
'p99_latency_ms': self._percentile(latencies, 99) if latencies else 0,
'error_rate': errors / iterations,
'total_queries': iterations
}
def concurrent_benchmark(self, query, params=None, duration_seconds=60):
"""Run concurrent load test"""
results = []
start_time = time.time()
with ThreadPoolExecutor(max_workers=self.num_connections) as executor:
futures = []
while time.time() - start_time < duration_seconds:
future = executor.submit(self.execute_query, query, params, 1)
futures.append(future)
time.sleep(0.1) # Control request rate
for future in as_completed(futures):
results.append(future.result())
return self._aggregate_results(results)
API Benchmark with Custom Metrics
const axios = require('axios');
const { performance } = require('perf_hooks');
class APIBenchmark {
constructor(baseURL, options = {}) {
this.client = axios.create({
baseURL,
timeout: options.timeout || 30000,
validateStatus: () => true // Don't throw on HTTP errors
});
this.metrics = [];
}
async benchmark(config) {
const {
method = 'GET',
endpoint,
payload,
headers = {},
iterations = 100,
concurrency = 1,
warmupIterations = 10
} = config;
// Warm-up phase
for (let i = 0; i < warmupIterations; i++) {
await this.singleRequest(method, endpoint, payload, headers);
}
// Benchmark phase
const promises = [];
const startTime = performance.now();
for (let i = 0; i < iterations; i++) {
if (promises.length >= concurrency) {
await Promise.race(promises);
promises.splice(promises.findIndex(p => p.settled), 1);
}
const promise = this.singleRequest(method, endpoint, payload, headers)
.then(result => {
promise.settled = true;
return result;
});
promises.push(promise);
}
await Promise.all(promises);
const totalDuration = performance.now() - startTime;
return this.calculateStatistics(totalDuration);
}
async singleRequest(method, endpoint, payload, headers) {
const startTime = performance.now();
const memoryBefore = process.memoryUsage();
try {
const response = await this.client({
method,
url: endpoint,
data: payload,
headers
});
const duration = performance.now() - startTime;
const memoryAfter = process.memoryUsage();
this.metrics.push({
duration,
statusCode: response.status,
responseSize: JSON.stringify(response.data).length,
memoryDelta: memoryAfter.heapUsed - memoryBefore.heapUsed,
timestamp: Date.now(),
success: response.status >= 200 && response.status < 400
});
return { duration, success: true, statusCode: response.status };
} catch (error) {
const duration = performance.now() - startTime;
this.metrics.push({
duration,
statusCode: error.response?.status || 0,
success: false,
error: error.message,
timestamp: Date.now()
});
return { duration, success: false, error: error.message };
}
}
calculateStatistics(totalDuration) {
const successful = this.metrics.filter(m => m.success);
const durations = successful.map(m => m.duration);
durations.sort((a, b) => a - b);
return {
totalRequests: this.metrics.length,
successfulRequests: successful.length,
errorRate: (this.metrics.length - successful.length) / this.metrics.length,
avgLatency: durations.reduce((a, b) => a + b, 0) / durations.length,
p50Latency: this.percentile(durations, 50),
p95Latency: this.percentile(durations, 95),
p99Latency: this.percentile(durations, 99),
throughput: (successful.length / totalDuration) * 1000, // requests per second
avgResponseSize: successful.reduce((sum, m) => sum + (m.responseSize || 0), 0) / successful.length
};
}
}
System Resource Monitoring
Comprehensive Monitoring Script
#!/bin/bash
### System Performance Monitoring During Benchmark
MONITOR_INTERVAL=5
OUTPUT_FILE="system_metrics_$(date +%Y%m%d_%H%M%S).csv"
### CSV Header
echo "timestamp,cpu_usage,memory_usage_mb,memory_percent,disk_io_read,disk_io_write,network_rx,network_tx,load_avg_1min" > $OUTPUT_FILE
monitor_system() {
while true; do
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
# CPU Usage
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')
# Memory Usage
MEMORY_INFO=$(free -m | grep '^Mem:')
MEMORY_TOTAL=$(echo $MEMORY_INFO | awk '{print $2}')
MEMORY_USED=$(echo $MEMORY_INFO | awk '{print $3}')
MEMORY_PERCENT=$(echo "scale=2; $MEMORY_USED * 100 / $MEMORY_TOTAL" | bc)
# Disk I/O
DISK_IO=$(iostat -d 1 2 | tail -n +4 | tail -n 1)
DISK_READ=$(echo $DISK_IO | awk '{print $3}')
DISK_WRITE=$(echo $DISK_IO | awk '{print $4}')
# Network I/O
NETWORK_IO=$(cat /proc/net/dev | grep eth0 | awk '{print $2,$10}')
NETWORK_RX=$(echo $NETWORK_IO | awk '{print $1}')
NETWORK_TX=$(echo $NETWORK_IO | awk '{print $2}')
# Load Average
LOAD_AVG=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')
echo "$TIMESTAMP,$CPU_USAGE,$MEMORY_USED,$MEMORY_PERCENT,$DISK_READ,$DISK_WRITE,$NETWORK_RX,$NETWORK_TX,$LOAD_AVG" >> $OUTPUT_FILE
sleep $MONITOR_INTERVAL
done
}
Best Practices and Recommendations
Test Environment Setup
- Isolate benchmark environment from other processes
- Use dedicated hardware or containers with resource limits
- Disable unnecessary services and background processes
- Configure consistent network conditions
- Document all environment specifications
Data Collection and Analysis
- Always collect baseline measurements before optimization
- Use correlation analysis to identify bottlenecks
- Implement automated regression detection
- Store historical results for trend analysis
- Create automated reports with visualizations
Common Pitfalls to Avoid
- Don't rely solely on average metrics; always include percentiles
- Avoid "cold start" measurements in final results
- Don't ignore system resource constraints
- Never benchmark in production without proper safeguards
- Don't optimize based on unrealistic test scenarios
Optimization Workflow
- Establish baseline performance metrics
- Identify performance bottlenecks through profiling
- Make targeted optimizations
- Re-run benchmarks to validate improvements
- Monitor for performance regressions
- Document changes and their performance impact
Always correlate benchmark results with business metrics and user experience indicators to ensure optimizations provide real-world value.
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.