15 Ready-to-Use Performance Testing Templates for Web, API, and Infrastructure
This article provides a collection of fifteen ready‑to‑use performance‑testing templates covering web page load, API peak load, database slow‑query, cache‑break, file‑upload bandwidth, WebSocket connections, microservice latency, OAuth2 flow, message‑queue lag, memory‑leak detection, SSL/TLS handshake, container CPU limits, and chaos‑mesh failover, each with clear objectives, tools, and sample code.
Template 1: Web Page Baseline Performance Test
Goal: Measure first‑screen load time < 2 s and First Contentful Paint (FCP) < 1.5 s for the e‑commerce homepage.
you are a mid‑level performance test engineer, design a baseline test for the e‑commerce homepage:
- URL: https://shop.example.com
- Metrics: first‑screen load time < 2s, FCP < 1.5s
- Tool: Locust + Playwright
- Output:
1. Test scenario description (including user behavior)
2. Locust script that integrates Playwright to measure front‑end metrics from locust import HttpUser, task
from playwright.sync_api import sync_playwright
class HomePageUser(HttpUser):
@task
def load_homepage(self):
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://shop.example.com")
# Get front‑end performance metrics
fcp = page.evaluate("performance.getEntriesByName('first-contentful-paint')[0].startTime")
load_time = page.evaluate("performance.timing.loadEventEnd - performance.timing.navigationStart")
# Report to Locust
self.environment.events.request_success.fire(
request_type="PAGE", name="/", response_time=load_time, response_length=0)
browser.close()Template 2: API Peak Load Test
Goal: Verify that the user‑query API can sustain 1 000 requests per second (RPS) with an error rate below 0.1 % while the database connection pool is limited to 100 connections.
Design a peak‑load test for the user‑query API:
- Endpoint: GET /api/v1/users?limit=100
- Target: 1000 RPS, error rate < 0.1 %
- Constraint: DB connection pool size = 100
- Generate a Locust script that includes dynamic parameters and result assertions. from locust import HttpUser, task, between
class UserQueryUser(HttpUser):
wait_time = between(1, 3)
@task
def get_users(self):
with self.client.get("/api/v1/users?limit=100", catch_response=True) as resp:
if resp.status_code != 200:
resp.failure(f"HTTP {resp.status_code}")
elif len(resp.json()) != 100:
resp.failure("Insufficient number of results")Template 3: Database Slow‑Query Load Test
Goal: Validate pagination performance on the orders table (10 000 rows, deep pagination page = 1000) and ensure the query finishes within 2 seconds while checking the execution plan.
Validate order‑table pagination performance:
- SQL: SELECT * FROM orders WHERE user_id=? ORDER BY created_at DESC LIMIT ?
- Scenario: 100 000 rows, deep pagination (page=1000)
- Tool: pytest + SQLAlchemy simulation
- Output test code that includes EXPLAIN analysis. import pytest
from sqlalchemy import text
def test_deep_pagination_performance(db_session):
# Insert 100 000 orders for user 1
for i in range(100000):
db_session.execute(text("INSERT INTO orders (user_id) VALUES (1)"))
db_session.commit()
# Test deep pagination
start_time = time.time()
result = db_session.execute(text("SELECT * FROM orders WHERE user_id=1 ORDER BY created_at DESC LIMIT 10 OFFSET 99990"))
query_time = time.time() - start_time
assert query_time < 2.0 # Must be < 2 s
# Verify index usage
explain = db_session.execute(text("EXPLAIN SELECT * FROM orders WHERE user_id=1 ORDER BY created_at DESC LIMIT 10"))
assert "Using index" in str(explain.fetchone())Template 4: Cache‑Break Scenario Test
Goal: Simulate a cache‑break on a product‑detail API (Redis TTL = 60 s) with 1 000 concurrent requests and observe whether the database QPS spikes.
Simulate cache‑break impact on product‑detail endpoint:
- Endpoint: GET /api/v1/products/123
- Cache: Redis, TTL = 60 s
- Scenario: Cache expires instantly, 1000 concurrent requests
- Generate a Gatling script to verify database QPS increase. class CacheBreakTest extends Simulation {
val httpProtocol = http.baseUrl("https://api.example.com")
val scn = scenario("Cache Break")
.exec(http("Product Detail").get("/api/v1/products/123"))
setUp(scn.inject(atOnceUsers(1000))).protocols(httpProtocol)
}Template 5: File Upload Bandwidth Test
Goal: Upload a 1 GB random binary file to the upload endpoint and achieve at least 80 % of a 1 Gbps network bandwidth.
Test large‑file upload bandwidth utilization:
- Endpoint: POST /api/v1/upload
- File: 1 GB random binary
- Target: Use >80 % of 1 Gbps bandwidth
- Generate a Python script using requests‑toolbelt for chunked upload and calculate throughput. import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
import time, os
def test_upload_bandwidth():
# Generate 1 GB random file
with open("large_file.bin", "wb") as f:
f.write(os.urandom(1024*1024*1024))
start_time = time.time()
with open("large_file.bin", "rb") as f:
encoder = MultipartEncoder({"file": ("large_file.bin", f, "application/octet-stream")})
resp = requests.post("/api/v1/upload", data=encoder, headers={"Content-Type": encoder.content_type})
duration = time.time() - start_time
throughput = (1024 / duration) # MB/s
assert throughput > 100 # >100 MB/s (~80 % of 1 Gbps)Template 6: WebSocket Connection Count Test
Goal: Verify that a WebSocket service can handle 10 000 concurrent connections while keeping memory usage under 4 GB.
Validate WebSocket service maximum connections:
- Service: wss://chat.example.com
- Target: Support 10 000 concurrent connections
- Monitor: Memory usage < 4 GB
- Generate an Artillery script that maintains connections and exchanges messages. # artillery.yaml
config:
target: "wss://chat.example.com"
phases:
- duration: 600
arrivalRate: 100 # 100 connections per second, 10 min reaches 60 k
engines:
ws: {}
scenarios:
- name: "Chat Connection"
engine: "ws"
flow:
- send: '{"type": "join", "room": "lobby"}'
- think: 300 # keep connection for 5 minTemplate 7: Microservice Chain Latency Test
Goal: Ensure end‑to‑end latency for order creation (API Gateway → Order Service → Payment Service → Inventory Service) stays below 1 s at the 99th percentile.
Test full‑chain latency for order creation:
- Chain: API Gateway → Order Service → Payment Service → Inventory Service
- Target: P99 < 1 s
- Tool: Jaeger + Locust
- Generate a test script that injects tracing headers and validates each segment's duration. import uuid
from locust import HttpUser, task
class OrderChainUser(HttpUser):
@task
def create_order(self):
trace_id = str(uuid.uuid4())
headers = {
"X-Request-ID": trace_id,
"Uber-Trace-ID": f"{trace_id}:1:1:1" # Jaeger format
}
self.client.post("/orders", json={"items": [...]}, headers=headers)
# Verify trace completeness in Jaeger
jaeger_resp = requests.get(f"http://jaeger:16686/api/traces/{trace_id}")
spans = jaeger_resp.json()["data"][0]["spans"]
total_latency = max(span["duration"] for span in spans) / 1e6 # seconds
assert total_latency < 1.0Template 8: Database Connection‑Pool Exhaustion Test
Goal: Simulate a Spring Boot application with HikariCP (maxPoolSize = 20) where 20 slow queries run concurrently; the 21st request should fail quickly (< 1 s).
Simulate DB connection‑pool exhaustion:
- Application: Spring Boot + HikariCP (maxPoolSize=20)
- Scenario: 20 slow queries (sleep 10 s) run simultaneously
- Verify: 21st request fails within 1 s
- Generate a JMeter script using JDBC Request. // JMeter BeanShell PreProcessor
import java.sql.*;
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://db:3306/test", "user", "pass");
Statement stmt = conn.createStatement();
stmt.execute("SELECT SLEEP(10)"); // slow query
} catch (SQLException e) {
if (e.getMessage().contains("timeout")) {
long duration = System.currentTimeMillis() - startTime;
if (duration < 1000) {
// Expected fast failure
}
}
} finally {
if (conn != null) conn.close();
}Template 9: CDN Cache‑Hit Rate Test
Goal: Ensure that a static asset (main.js) served via CDN receives fewer than 10 origin requests during a 1 000‑user concurrent load, i.e., cache‑hit rate > 99 %.
Validate CDN cache effectiveness for static resources:
- Resource: /static/main.js (Cache‑Control: max‑age=3600)
- Scenario: 1000 concurrent users
- Target: < 10 origin requests (hit rate > 99 %)
- Generate a k6 script that checks the X‑Cache response header. // k6 script
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = { vus: 1000, duration: '30s' };
export default function () {
const res = http.get('https://cdn.example.com/static/main.js');
check(res, { 'CDN hit': (r) => r.headers['X-Cache'] === 'HIT' });
sleep(1);
}Template 10: OAuth2.0 Authorization‑Code Performance Test
Goal: Complete the full OAuth2.0 authorization‑code flow (authorize → token → API call) in under 500 ms with 100 concurrent users per second.
Test OAuth2.0 authorization‑code flow performance:
- Flow: /authorize → /token → API call
- Target: Single flow < 500 ms
- Concurrency: 100 users/second
- Generate a Locust script that manages session state. class OAuthUser(HttpUser):
def on_start(self):
# Get authorization code
auth_resp = self.client.get("/oauth/authorize?client_id=test&redirect_uri=https://example.com/callback")
auth_code = extract_code_from_url(auth_resp.url)
# Exchange for token
token_resp = self.client.post("/oauth/token", data={
"grant_type": "authorization_code",
"code": auth_code,
"redirect_uri": "https://example.com/callback"
})
self.access_token = token_resp.json()["access_token"]
@task
def call_api(self):
self.client.get("/api/data", headers={"Authorization": f"Bearer {self.access_token}"})Template 11: Message‑Queue Backlog Test
Goal: Verify that a Kafka consumer can keep up with a production rate of 1 000 messages per second, processing each message in 10 ms, resulting in zero lag.
Validate Kafka consumer processing capacity:
- Topic: order-events
- Production rate: 1000 msg/s
- Consumer: single instance, 10 ms per message
- Target: No backlog (lag = 0)
- Generate a test script that monitors consumer lag. import time
from kafka import KafkaConsumer, KafkaProducer
def test_kafka_lag():
producer = KafkaProducer(bootstrap_servers='kafka:9092')
consumer = KafkaConsumer('order-events', bootstrap_servers='kafka:9092')
for i in range(1000):
producer.send('order-events', b'message')
producer.flush()
start_time = time.time()
for msg in consumer:
time.sleep(0.01) # 10 ms processing
if time.time() - start_time > 10:
break
lag = get_consumer_lag('order-events', 'test-group')
assert lag == 0Template 12: Multi‑Region Latency Test
Goal: Measure API health‑check latency from AWS us‑east‑1, eu‑west‑1, and ap‑southeast‑1, keeping the 95th percentile below 200 ms.
Test global user latency:
- Regions: AWS us-east-1, eu-west-1, ap-southeast-1
- Endpoint: GET /api/health
- Target: P95 < 200 ms per region
- Generate a distributed test plan using AWS Lambda. # AWS Lambda function
import boto3, requests, time
def lambda_handler(event, context):
region = event['region']
start = time.time()
resp = requests.get(f"https://{region}.api.example.com/health")
latency = (time.time() - start) * 1000
cloudwatch = boto3.client('cloudwatch', region_name=region)
cloudwatch.put_metric_data(Namespace='APIPerformance', MetricData=[{'MetricName': 'Latency', 'Value': latency, 'Unit': 'Milliseconds'}])
return {'latency_ms': latency}Template 13: Memory‑Leak Detection Test
Goal: Run a Node.js API for one hour at 100 RPS and ensure memory growth stays below 10 MB per hour.
Validate memory leak over prolonged run:
- Service: Node.js API
- Scenario: 1 hour, 100 RPS
- Monitor: Memory increase < 10 MB/hour
- Generate a test script that periodically samples heap usage. import psutil, time, requests
def test_memory_leak():
process = psutil.Process(get_nodejs_pid())
initial_memory = process.memory_info().rss / 1024 / 1024 # MB
start_time = time.time()
while time.time() - start_time < 3600:
requests.get("/api/data")
time.sleep(0.01) # 100 RPS
final_memory = process.memory_info().rss / 1024 / 1024
memory_growth = final_memory - initial_memory
assert memory_growth < 10Template 14: SSL/TLS Handshake Performance Test
Goal: Compare TLS 1.3 vs TLS 1.2 handshake times, ensuring TLS 1.3 completes in under 50 ms.
Test HTTPS handshake performance:
- Protocols: TLS 1.3 vs TLS 1.2
- Target: TLS 1.3 handshake time < 50 ms
- Tool: OpenSSL s_time for simulation
- Generate comparative test scripts. # TLS 1.3 test
openssl s_time -connect api.example.com:443 -www -tls1_3 -time 10
# TLS 1.2 test
openssl s_time -connect api.example.com:443 -www -tls1_2 -time 10
# Parse results
grep "Average" tls13.log | awk '{print $2}' # should be < 50Template 15: Containerized Application Resource‑Limit Test
Goal: Verify that a Docker container limited to 0.5 CPU cores actually uses roughly 50 % CPU while running a CPU‑intensive Fibonacci calculation.
Validate Docker CPU limit effect:
- Limit: CPU 0.5 core
- Application: CPU‑intensive task (Fibonacci)
- Target: Actual CPU usage ≈ 50 %
- Generate a test script that monitors cgroup stats. import subprocess, time
def test_cpu_limit():
# Start constrained container
subprocess.run(["docker", "run", "-d", "--cpus=0.5", "--name=cpu-test", "cpu-stress-image"])
start_time = time.time()
while time.time() - start_time < 60:
cpu_usage = float(subprocess.check_output([
"docker", "stats", "--no-stream", "--format", "{{.CPUPerc}}", "cpu-test"
]).decode().strip().rstrip('%'))
if abs(cpu_usage - 50) > 10:
raise AssertionError(f"CPU usage {cpu_usage}% not near 50%")
time.sleep(5)Template 16: Fault‑Injection Recovery Test
Goal: Kill the primary MySQL process, let Sentinel promote the replica, and ensure API error rate stays below 5 % with recovery time under 30 seconds.
Test API availability during DB master‑slave failover:
- Fault: kill primary MySQL process
- Recovery: Sentinel auto‑switch to replica
- Target: API error rate < 5 %, recovery time < 30 s
- Generate a Chaos Mesh experiment script. # chaos-mesh experiment
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
name: mysql-kill
spec:
action: pod-kill
mode: one
selector:
namespaces: ["prod"]
labelSelectors:
app: mysql-master
scheduler:
cron: "@every 5m"
---
# Verification script
import time, requests
def test_failover():
errors = 0
start_time = time.time()
while time.time() - start_time < 60:
try:
requests.get("/api/orders")
except:
errors += 1
time.sleep(1)
error_rate = errors / 60
assert error_rate < 0.05Usage Guide
Replace placeholders such as example.com and metric thresholds with values that match your actual system.
Combine multiple templates for complex scenarios (e.g., microservice chain + fault injection).
Integrate test results into Prometheus/Grafana for visualization.
Pair Grafana with k6 or Locust + InfluxDB to achieve a closed‑loop performance testing workflow.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
