Skip to content

sen-ltd/http-bench

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

http-bench

A minimal wrk-like HTTP load tester in Rust. Fires HTTP requests at a target for a fixed duration or request count, and reports RPS, full latency percentiles (via HDR histograms), status distribution, and error breakdown.

screenshot

  • wrk is excellent but C and a pain to compile on a fresh box.
  • hey is Go and doesn't give you p99 by default.
  • oha is close to what I wanted but ships a TUI I don't need from a headless bench.

http-bench is ~900 lines of Rust across five source files, five dependencies (clap, tokio, reqwest with rustls, hdrhistogram, humantime), and ships as an 11.6 MB multi-stage Alpine container.

Quick start

# Hit a local server for 10 seconds with 10 workers (all defaults).
http-bench http://localhost:8080/

# Fixed request count.
http-bench http://localhost:8080/ --requests 10000 --concurrency 50

# POST with a body and header.
http-bench http://localhost:8080/items \
    --method post \
    --header "Content-Type: application/json" \
    --body '{"name":"x"}' \
    --duration 30s

# Machine-readable output for CI dashboards.
http-bench http://localhost:8080/ --duration 5s --format json

Docker

docker build -t http-bench .

# Private target, no flag needed.
docker run --rm --network host http-bench http://127.0.0.1:8080/ --duration 5s

# Public target — requires --allow-internet.
docker run --rm http-bench https://example.com \
    --allow-internet --duration 2s --concurrency 2

Example output (text)

http-bench report
=================
Duration:    2.01 s
Concurrency: 2
Total:       393 requests
RPS:         195.73
Per-worker:  min 97.62 / mean 97.89 / max 98.17 RPS

Status distribution
-------------------
2xx: 393
3xx: 0
4xx: 0
5xx: 0

Errors
------
connect: 0
timeout: 0
other:   0

Latency (successful requests)
-----------------------------
min:  8.69 ms
mean: 10.20 ms
p50:  9.93 ms
p90:  10.70 ms
p99:  18.29 ms
max:  48.09 ms

The safety gate

By default, http-bench refuses to hit a target that isn't obviously yours. Private, loopback, link-local, and *.local addresses are allowed without a flag; anything else requires --allow-internet. You can turn this off with one flag, but you can't turn it off by accident.

This is parallel to port-scanner's --allow-remote. Load tests against someone else's server can, depending on terms of service and jurisdiction, range from impolite to prosecutable; putting a one-word flag in front of that boundary feels like the right trade-off.

Exit codes

Code Meaning
0 Bench completed. HTTP 4xx and 5xx are not errors — they're recorded in the report.
1 Zero requests succeeded; every attempt failed at the connect layer.
2 Bad arguments, invalid URL, or safety gate refused the target.

Build and test

cargo build --release
cargo test

Tests include unit tests for the histogram, report formatter, CLI validator, and safety classifier, plus integration tests that spawn a hand-rolled tokio HTTP server on a random loopback port and run the binary against it.

License

MIT. See LICENSE.

Links

About

A minimal wrk-like HTTP load tester in Rust, written because wrk is C and painful to get onto a fresh box, hey doesn't give you p99 by default, and oha ships a TUI I don't want from a headless bench.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors