Web server performance benchmarking setup for comparing multiple HTTP servers across realistic scenarios.
client/ Load generation client
benchmark.py h2load wrapper that sweeps concurrency levels and writes CSV results
server/ Server provisioning and configuration
bench CLI entry point for building, configuring, and starting servers
lib/ Shell libraries (build, config, certs, docker, etc.)
scenarios/ Per-scenario config templates (1-5)
backends/ Node.js backend servers for reverse-proxy scenarios
payloads/ Test file generation (10KB + 2MB)
wp/ WordPress bootstrap for scenario 3
test/ Docker-based automated validation
cd server
# Install build dependencies (Ubuntu)
sudo apt-get install -y build-essential autoconf automake libtool cmake pkg-config clang \
libpcre2-dev zlib1g-dev libssl-dev libzstd-dev golang-go curl wget jq
# For Rust servers
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source ~/.cargo/env
# Build a server (e.g. ferron3)
bench build ferron3
# Generate TLS certs and test payloads
bench generate-certs
bench generate-payloads
# Start the server
bench start scenario1-zstd ferron3cd client
# Sweep concurrency from 1 to 256 in steps of 32
python benchmark.py https://localhost 256 32 results.csvSee server/README.md for the full CLI reference, supported servers, scenarios, and troubleshooting.
| Server | Language | Scenarios |
|---|---|---|
| NGINX | C | 1, 2, 3, 4, 5 |
| Apache HTTP Server | C | 1, 3 |
| Caddy | Go | 1, 2, 4, 5 |
| HAProxy | C | 2 |
| Traefik | Go | 2 |
| Ferron 2 | Rust | 1, 2, 4 |
| Ferron 3 | Rust | 1, 2, 3, 4, 5 |
| OpenLiteSpeed | C/C++ | 3 |
| Scenario | Description |
|---|---|
| scenario1-zstd | Static file serving with Zstd compression |
| scenario2-reverse-proxy | Reverse proxy and load balancing to 4 Node.js backends |
| scenario3-wordpress | Cached WordPress with PHP-FPM |
| scenario4-observability | Observability overhead (the "telemetry tax") |
| scenario5-http3 | HTTP/3 (QUIC) — experimental |