<div align="center">
# httpress
[](https://crates.io/crates/httpress)
[](https://crates.io/crates/httpress)
[](https://docs.rs/httpress)
[](https://github.com/TecuceanuGabriel/httpress/actions/workflows/ci.yml)
[](https://github.com/TecuceanuGabriel/httpress)
a fast HTTP benchmarking library and CLI tool

</div>
## Contents
- [Features](#features)
- [Performance](#performance)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Library Usage](#library-usage)
- [Basic Benchmark](#basic-benchmark)
- [Custom Request Generation](#custom-request-generation)
- [Dynamic Rate Control](#dynamic-rate-control)
- [Hook System](#hook-system)
- [CLI Usage](#cli-usage)
- [Basic Examples](#basic-examples)
- [Options](#options)
- [Examples](#examples)
## Features
- **High Performance** - async rust with minimal overhead
- **Detailed Metrics** - latency percentiles, throughput, status code breakdown
- **Flexible Stop Conditions** - duration, request-count or infinite
- **Concurrent Workers** - configure the number of concurrent connections
- **Library + CLI** - use as a rust library or standalone tool
- **Flexible Rate Control** - use fixed rates or dynamic rate functions
- **Custom Request Generation** - generate requests dynamically per-worker
- **Hook System** - inject custom logic before/after each request
- **Simple Builder API** - easy to use, type-safe configuration
## Performance
- Benchmarks run against a local [hyper](https://hyper.rs/) echo server.
- Environment: Intel Core i5-8350U, Arch Linux x86_64.
### Scaling
| 5 | 17,315 req/s | 0.25 ms | 0.57 ms |
| 10 | 20,909 req/s | 0.39 ms | 1.10 ms |
| 25 | 29,071 req/s | 0.70 ms | 1.64 ms |
| 50 | 32,000 req/s | 1.25 ms | 2.90 ms |
| 100 | 32,502 req/s | 2.42 ms | 6.03 ms |
### Comparison to other similar tools (concurrency=100, 10 s)
| httpress | 32,502 req/s | 2.42 ms | 6.03 ms |
| wrk¹ | 39,135 req/s | 2.47 ms | 5.42 ms |
| hey | 27,182 req/s | 3.50 ms | 9.40 ms |
### Sample output
```
Target: http://localhost:3000 Get
Concurrency: 100
Stop condition: Duration(10s)
Starting benchmark with 100 workers...
--- Benchmark Complete ---
Requests: 325107 total, 325107 success, 0 errors
Duration: 10.00s
Throughput: 32502.23 req/s
Transferred: 0.62 MB
Latency:
Min: 175us
Max: 45.12ms
Mean: 2.52ms
p50: 2.42ms
p90: 3.91ms
p95: 4.43ms
p99: 6.03ms
Status codes:
200: 325107
```
## Installation
### As a CLI Tool
```bash
cargo install httpress
```
### As a Library
Add to your `Cargo.toml`:
```toml
[dependencies]
httpress = "0.6"
tokio = { version = "1", features = ["full"] }
```
## Quick Start
```rust
use httpress::{Benchmark, Result};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<()> {
let results = Benchmark::builder()
.url("http://localhost:3000")
.concurrency(50)
.duration(Duration::from_secs(10))
.show_progress(true)
.build()?
.run()
.await?;
results.print();
Ok(())
}
```
## CLI Usage
### Basic Examples
```bash
# Run benchmark with 100 concurrent connections for 30 seconds
httpress http://example.com -c 100 -d 30s
# Fixed number of requests with rate limiting
httpress http://example.com -n 10000 -r 1000
# POST request with headers and body
httpress http://example.com/api -m POST \
-H "Content-Type: application/json" \
-b '{"key": "value"}'
# Run until interrupted (Ctrl+C)
httpress http://example.com -c 50
```
### Options
| `-n, --requests` | Total number of requests | - |
| `-d, --duration` | Test duration (e.g. 10s, 1m) | - |
| `-c, --concurrency` | Concurrent connections | 10 |
| `-r, --rate` | Rate limit (req/s) | - |
| `-m, --method` | HTTP method | GET |
| `-H, --header` | HTTP header (repeatable) | - |
| `-b, --body` | Request body | - |
| `-t, --timeout` | Request timeout in seconds | 30 |
## Library Usage
### Basic Benchmark
```rust
let results = Benchmark::builder()
.url("http://localhost:3000")
.concurrency(50)
.requests(1000)
.show_progress(true)
.build()?
.run()
.await?;
```
### Custom Request Generation
```rust
.request_fn(|ctx: RequestContext| {
let user_id = ctx.request_number % 100;
RequestConfig {
url: format!("http://localhost:3000/user/{}", user_id),
method: HttpMethod::Get,
headers: HashMap::new(),
body: None,
}
})
```
### Dynamic Rate Control
```rust
.rate_fn(|ctx: RateContext| {
let progress = (ctx.elapsed.as_secs_f64() / 10.0).min(1.0);
100.0 + (900.0 * progress) // ramp from 100 to 1000 req/s
})
```
### Hook System
#### Before-request
You can use these for circuit breakers or conditional execution:
```rust
.before_request(|ctx: BeforeRequestContext| {
let failure_rate = ctx.failed_requests as f64 / ctx.total_requests.max(1) as f64;
if failure_rate > 0.5 && ctx.total_requests > 100 {
HookAction::Abort
} else {
HookAction::Continue
}
})
```
#### After-request
You can use them to collect custom metrics or write retry logic:
```rust
.after_request(|ctx: AfterRequestContext| {
if let Some(status) = ctx.status {
if status >= 500 {
return HookAction::Retry;
}
}
HookAction::Continue
})
.max_retries(3)
```
For complete API documentation, see [docs.rs/httpress](https://docs.rs/httpress).
## Examples
The `examples/` directory contains:
- **basic_benchmark.rs** - basic benchmark example
- **custom_requests.rs** - dynamic request generation using `request_fn`
- **rate_ramping.rs** - advanced rate control using `rate_fn`
- **hooks_metrics.rs** - custom metrics collection using hooks
Run examples with:
```bash
cargo run --example basic_benchmark
```