http-load-testing

v2026.09.24

HTTP load testing with oha. Use when measuring latency percentiles, finding a server's breaking point, or validating SLA targets under coordinated-omission correction.

GitHub
Install command
npx skhub add laurigates/http-load-testing
Markdown
SKILL.md

HTTP Load Testing

When to Use This Skill

ScenarioUse this skillAlternative
Benchmark an API endpoint's throughputYes
Measure latency percentiles (p50/p90/p99)Yes
Find the breaking point of a serviceYes
Validate SLA targets under sustained loadYes
Compare latency with/without coordinated omissionYes
Troubleshoot why a single request is slownetwork-diagnostics (trippy, gping)
Resolve a domain name or check DNS recordsdns-tools (dog, dig)
Scan for open ports on a hostnetwork-discovery (RustScan, nmap)
See which process is consuming bandwidthnetwork-monitoring (bandwhich)
Map physical switch topologylayer2-discovery (LLDP, ARP)
Inspect or configure the host's own IPs, links, or routesinterface-state (ip)

Expert knowledge for HTTP load testing using oha, a Rust-based load generator with real-time TUI visualization and proper latency measurement.

Core Concepts

Coordinated Omission Problem

Traditional load testers measure only the time from request send to response received. This misses queuing delays when the server slows down, leading to optimistic latency numbers.

Example: If your target is 100 RPS but the server can only handle 50 RPS:

  • Without correction: Measures only successful request latencies (looks good)
  • With correction: Accounts for requests that couldn't be sent on schedule (reveals true user experience)

oha addresses this with --latency-correction (enabled by default).

Latency Percentiles

PercentileMeaningUse Case
p50 (median)Half of requests fasterTypical user experience
p9090% of requests fasterMost users' experience
p9999% of requests fasterTail latency, SLA targets
p99.999.9% of requests fasterWorst-case scenarios

Rule of thumb: Focus on p99 for SLAs. A 100ms p50 with 2s p99 indicates serious tail latency issues.

Why oha

Featureohawrkvegetahey
Latency correctionYes (default)NoNoNo
Real-time TUIYesNoNoNo
HTTP/2YesNoYesYes
HTTP/3 (experimental)YesNoNoNo
ScriptingNoLuaNoNo
CI-friendly outputYes (JSON)LimitedYesYes
Active maintenanceYesLimitedYesNo

Installation

# macOS
brew install oha

# Cargo (any platform)
cargo install oha

# Verify
oha --version

Essential Commands

Basic Load Test

# 200 requests with 50 concurrent connections
oha -n 200 -c 50 https://api.example.com/health

# Run for 30 seconds
oha -z 30s -c 50 https://api.example.com/health

# Target specific requests per second (QPS)
oha -q 100 -z 30s https://api.example.com/health

Request Configuration

# POST with JSON body
oha -m POST -H "Content-Type: application/json" -d '{"key":"value"}' https://api.example.com/data

# Custom headers
oha -H "Authorization: Bearer TOKEN" -H "X-Custom: value" https://api.example.com/protected

# Request body from file
oha -m POST -D @request.json https://api.example.com/data

Connection Settings

# HTTP/2
oha --http-version 2 https://api.example.com/health

# Disable keep-alive (new connection per request)
oha --disable-keepalive https://api.example.com/health

# Connection timeout
oha --timeout 10s https://api.example.com/slow-endpoint

TUI and Output Control

# Disable TUI (for scripts/CI)
oha --no-tui -n 1000 https://api.example.com/health

# JSON output for parsing
oha --no-tui -j -n 1000 https://api.example.com/health

# Disable latency correction (compare with corrected)
oha --no-tui --disable-latency-correction -n 1000 https://api.example.com/health

Common Patterns

Quick Health Check

# Fast sanity check - 100 requests, 10 connections
oha -n 100 -c 10 --no-tui https://api.example.com/health

Sustained Load Test

# 5 minutes at 100 RPS with 50 connections
oha -z 5m -q 100 -c 50 https://api.example.com/endpoint

Find Breaking Point

# Gradually increase load
for qps in 50 100 200 400 800; do
  echo "Testing at $qps RPS..."
  oha --no-tui -j -z 30s -q $qps https://api.example.com/health | jq '.summary'
done

Compare With/Without Latency Correction

# Shows the coordinated omission effect
echo "With correction:"
oha --no-tui -z 30s -q 500 https://api.example.com/health

echo "Without correction:"
oha --no-tui --disable-latency-correction -z 30s -q 500 https://api.example.com/health

POST Endpoint Load Test

oha -m POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"user_id": 123, "action": "test"}' \
  -z 60s -c 20 \
  https://api.example.com/events

Interpreting Results

TUI Display

The real-time TUI shows:

  • Request rate (current/target)
  • Latency histogram
  • Status code distribution
  • Error rate

JSON Output Fields

oha --no-tui -j -n 1000 https://api.example.com/health | jq '.'

Key fields:

  • .summary.successRate - Percentage of 2xx responses
  • .summary.total - Total requests sent
  • .summary.slowest - Maximum latency
  • .summary.fastest - Minimum latency
  • .summary.average - Mean latency
  • .latencyDistribution - Percentile breakdown (p50, p90, p99, etc.)
  • .statusCodeDistribution - Count per HTTP status code

What to Look For

MetricGoodConcerningCritical
Success rate>99.9%99-99.9%<99%
p99/p50 ratio<5x5-10x>10x
Error rate0%<1%>1%
p99 latency<SLA targetNear SLA>SLA

Alternative Tools

wrk/wrk2

High-throughput benchmarking with Lua scripting.

# Basic test
wrk -t12 -c400 -d30s https://api.example.com/health

# With Lua script for custom requests
wrk -t12 -c400 -d30s -s script.lua https://api.example.com/

Use when: Need Lua scripting for complex request patterns or maximum throughput testing.

Limitation: Does not handle coordinated omission.

vegeta

Go-based load tester with attack/report workflow.

# Generate constant load
echo "GET https://api.example.com/health" | vegeta attack -rate=100/s -duration=30s | vegeta report

# JSON output
echo "GET https://api.example.com/health" | vegeta attack -rate=100/s -duration=30s | vegeta encode --to json

# Plot latencies
echo "GET https://api.example.com/health" | vegeta attack -rate=100/s -duration=30s | vegeta plot > plot.html

Use when: Need CI-friendly pipeline workflow or latency plots.

Limitation: Does not correct for coordinated omission.

hey

Simple HTTP load generator (successor to ab).

# 10000 requests, 100 concurrent
hey -n 10000 -c 100 https://api.example.com/health

# Rate limited
hey -n 10000 -c 100 -q 50 https://api.example.com/health

Use when: Quick ad-hoc testing, familiar with ab.

Limitation: Unmaintained, no coordinated omission handling.

Agentic Optimizations

ContextCommand
Quick testoha --no-tui -n 100 -c 10 $URL
CI pipelineoha --no-tui -j -z 30s -q 100 $URL
JSON parsingoha --no-tui -j $URL | jq '.summary'
Success rateoha --no-tui -j $URL | jq '.summary.successRate'
Latency p99oha --no-tui -j $URL | jq '.latencyDistribution."99"'
Fail on errorsoha --no-tui -j $URL | jq -e '.summary.successRate > 99'

Quick Reference

Core Flags

FlagDescriptionDefault
-n, --numberTotal requests to send200
-c, --connectionsConcurrent connections50
-z, --durationTest duration (e.g., 30s, 5m)-
-q, --query-per-secondTarget QPS rate limitunlimited

Request Flags

FlagDescription
-m, --methodHTTP method (GET, POST, etc.)
-H, --headerAdd header (repeatable)
-d, --dataRequest body
-D, --data-fileRequest body from file

Output Flags

FlagDescription
--no-tuiDisable real-time TUI
-j, --jsonJSON output (requires --no-tui)
--disable-latency-correctionDisable coordinated omission fix

Connection Flags

FlagDescription
--http-version1.0, 1.1, or 2
--disable-keepaliveNew connection per request
--timeoutRequest timeout
--connect-timeoutConnection timeout

Resources

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

networking-plugin/skills/http-load-testing

Default branch

main

Latest commit

1668324

Tree SHA

b2d4cc3