HttpArena
Knowledge BaseFrameworks

Test Profiles

HttpArena runs every framework through multiple benchmark profiles. Each profile isolates a different performance dimension, ensuring frameworks are compared fairly across varied workloads.

Your framework must implement endpoints depending on which test profiles it participates in. All HTTP/1.1 endpoints are served on port 8080. HTTPS/H2/H3 endpoints are served on port 8443.

Each profile is run at multiple connection counts to show how frameworks scale under increasing concurrency.

API Specification

All benchmark endpoints are described in machine-readable OpenAPI 3.0 specifications. Each spec covers request/response schemas, status codes, standard and tuned implementation rules, and links back to the relevant documentation pages.

The endpoints are split across two files:

SpecProfiles covered
openapi.jsonAll HTTP/1.1, HTTP/2, HTTP/3, gRPC, and WebSocket profilesBrowse
openapi-gateway.jsonGateway profiles (production-stack)Browse

Benchmark parameters

Five load generators are dispatched per profile - each one is built for a specific protocol + workload shape. See Load Generators for per-tool details.

ParameterValue
Load generatorsgcannon (HTTP/1.1, WebSocket), wrk (static, json-tls and 8gbit rotation), h2load (HTTP/2, h2c, gateway), h2load-h3 (HTTP/3 / QUIC), zrk (fixed-rate)
Threads64 for gcannon / wrk / h2load / h2load-h3 ($THREADS / $H2THREADS / $H3THREADS)
Duration5s default; async-db 10s (hardcoded in the profile dispatcher)
Runs3 per (profile, connection count) - best RPS wins
NetworkingDocker --network host for all containers (server + load generator + Postgres + Redis sidecars)

Data mounts

Data files are mounted automatically by the benchmark runner - your Dockerfile does not need to include them. The following paths are available inside the container at runtime:

PathDescription
/data/dataset.json50-item dataset for /json, /db, and /async-db
/data/static/20 static assets for /static/* (HTML, JS, CSS, SVG, WebP, woff2, JSON). 15 assets ship with pre-built .gz and .br sibling files (e.g. app.js, app.js.gz, app.js.br) so frameworks that support precompressed serving can skip on-the-fly compression. The 5 already-binary formats (hero.webp, thumb1.webp, thumb2.webp, bold.woff2, regular.woff2) have no precompressed variants. See the Static TLS profile for how to wire Accept-Encoding lookup.
/certs/server.crt, /certs/server.keyTLS certificate and key for HTTPS / H2 / H2 h2c (port 8082 is cleartext) / H3

Environment variables

Set by the benchmark runner when the relevant profile runs - your process will see them via os.environ / std::env::var / equivalent.

VariableProfilesValue
DATABASE_URLasync-db, fortunesPostgres connection string (postgres://bench:bench@127.0.0.1:5432/benchmark)
DATABASE_MAX_CONNsame as above256 - the Postgres sidecar's max_connections; size your pool ≤ this

Gateway and production-stack profiles are compose-orchestrated, so their services receive additional env (e.g. JWT_SECRET for the production-stack auth sidecar) via their compose.*.yml files rather than through the runner. See the per-profile pages under Gateway for details.