Skill

Benchmark System Performance Accurately

Designs performance benchmarks: Artillery load tests, database/API latency measurement, and system resource monitoring.

Works with githubartillerypostgresqlaxios

Maintainer of this project? Claim this page to edit the listing.


80
Spark score
out of 100
Updated 7 months ago
Version 1.0.0
Models

Add 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

01

Design and implement statistically valid performance benchmark strategies.

02

Execute load tests using tools like Artillery for API performance.

03

Conduct database performance testing with detailed metric analysis.

04

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

  1. Establish baseline performance metrics
  2. Identify performance bottlenecks through profiling
  3. Make targeted optimizations
  4. Re-run benchmarks to validate improvements
  5. Monitor for performance regressions
  6. 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.