High-performance Rust HTTP load tester with multiple load models and Prometheus metrics
10K+
A high-performance, Rust-based HTTP load testing tool designed for comprehensive service performance testing. Generate realistic traffic patterns, collect Prometheus metrics, and stress-test your endpoints with various load profiles.
# Standard Ubuntu-based image - great for development and debugging
docker run --rm \
-e TARGET_URL="https://your-api.com/endpoint" \
-e LOAD_MODEL_TYPE="Concurrent" \
-e NUM_CONCURRENT_TASKS="50" \
-e TEST_DURATION="5m" \
cbaugus/rust-loadtester:latest
# Chainguard static image - production-ready, minimal CVEs
docker run --rm \
-e TARGET_URL="https://your-api.com/endpoint" \
-e LOAD_MODEL_TYPE="Rps" \
-e TARGET_RPS="200" \
-e NUM_CONCURRENT_TASKS="100" \
-e TEST_DURATION="10m" \
cbaugus/rust-loadtester:latest-Chainguard
Tags: latest, main, <branch-name>
Tags: latest-Chainguard, main-Chainguard, <branch-name>-Chainguard
docker run --rm \
-e TARGET_URL="https://api.example.com/users" \
-e REQUEST_TYPE="GET" \
-e LOAD_MODEL_TYPE="Rps" \
-e TARGET_RPS="500" \
-e NUM_CONCURRENT_TASKS="100" \
-e TEST_DURATION="15m" \
cbaugus/rust-loadtester:latest-Chainguard
docker run --rm \
-e TARGET_URL="https://api.example.com/login" \
-e REQUEST_TYPE="POST" \
-e SEND_JSON="true" \
-e JSON_PAYLOAD='{"username":"testuser","password":"testpass"}' \
-e LOAD_MODEL_TYPE="Concurrent" \
-e NUM_CONCURRENT_TASKS="20" \
-e TEST_DURATION="10m" \
cbaugus/rust-loadtester:latest
docker run --rm \
-e TARGET_URL="https://your-service.com/api" \
-e LOAD_MODEL_TYPE="DailyTraffic" \
-e DAILY_MIN_RPS="10" \
-e DAILY_MID_RPS="200" \
-e DAILY_MAX_RPS="1000" \
-e DAILY_CYCLE_DURATION="24h" \
-e NUM_CONCURRENT_TASKS="200" \
-e TEST_DURATION="48h" \
cbaugus/rust-loadtester:latest-Chainguard
docker run --rm \
-e TARGET_URL="https://api.example.com/protected" \
-e CUSTOM_HEADERS="Authorization: Bearer your_token,X-Api-Key:your_key" \
-e LOAD_MODEL_TYPE="Concurrent" \
-e NUM_CONCURRENT_TASKS="50" \
-e TEST_DURATION="5m" \
cbaugus/rust-loadtester:latest
docker run --rm \
-e TARGET_URL="https://api.example.com/endpoint" \
-e LOAD_MODEL_TYPE="RampRps" \
-e MIN_RPS="50" \
-e MAX_RPS="500" \
-e NUM_CONCURRENT_TASKS="150" \
-e TEST_DURATION="15m" \
cbaugus/rust-loadtester:latest-Chainguard
| Variable | Required | Default | Description |
|---|---|---|---|
TARGET_URL | Yes | - | Full URL of the endpoint to test |
LOAD_MODEL_TYPE | Yes | - | Load model: Concurrent, Rps, RampRps, or DailyTraffic |
NUM_CONCURRENT_TASKS | No | 10 | Maximum concurrent requests |
TEST_DURATION | No | 2h | Test duration (e.g., 10m, 1h, 3d) |
REQUEST_TYPE | No | GET | HTTP method: GET or POST |
SKIP_TLS_VERIFY | No | false | Skip TLS certificate verification |
CLUSTER_NODE_ID | No | hostname | Node identifier used in metrics labels |
CLUSTER_REGION | No | default | Region label used in metrics and health output |
CLUSTER_HEALTH_ADDR | No | 0.0.0.0:8080 | Bind address for the live control HTTP API |
LOG_FORMAT | No | pretty | Log output format: json for structured GCP/FluentBit logs, any other value for human-readable |
RUST_LOG | No | rust_loadtest=info | Log level filter (e.g. rust_loadtest=warn,hyper=error,reqwest=error) |
RPS Model:
TARGET_RPS: Target requests per secondRampRps Model:
MIN_RPS: Starting/ending RPSMAX_RPS: Peak RPSRAMP_DURATION: Total ramp profile durationDailyTraffic Model:
DAILY_MIN_RPS: Base load (night-time)DAILY_MID_RPS: Mid-level load (afternoon)DAILY_MAX_RPS: Peak load (morning rush)DAILY_CYCLE_DURATION: Duration of one full cycleAccess metrics at http://<container-host>:9090/metrics
# View metrics
curl http://localhost:9090/metrics
# Example metrics available:
# - loadtest_requests_total
# - loadtest_status_codes
# - loadtest_concurrent_requests
docker run --rm \
-v /local/path/to/client.crt:/etc/ssl/certs/client.crt \
-v /local/path/to/client.key:/etc/ssl/private/client.key \
-e TARGET_URL="https://secure-api.com/endpoint" \
-e CLIENT_CERT_PATH="/etc/ssl/certs/client.crt" \
-e CLIENT_KEY_PATH="/etc/ssl/private/client.key" \
-e LOAD_MODEL_TYPE="Concurrent" \
-e NUM_CONCURRENT_TASKS="50" \
-e TEST_DURATION="10m" \
cbaugus/rust-loadtester:latest-Chainguard
Note: Private keys must be in PKCS#8 format. Convert if needed:
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \
-in original.key -out pkcs8.key
Set LOG_FORMAT=json to emit one structured JSON object per log line instead of
human-readable text. Required for FluentBit to unpack fields into GCP Cloud Logging
jsonPayload so they are indexed, filterable, and priced as structured logs.
docker run --rm \
-e LOG_FORMAT=json \
-e RUST_LOG="rust_loadtest=warn,hyper=error,reqwest=error" \
-e TARGET_URL="https://api.example.com/endpoint" \
-e LOAD_MODEL_TYPE="Rps" \
-e TARGET_RPS="200" \
cbaugus/rust_loadtest:latest
Example JSON log line:
{"timestamp":"2026-03-16T20:39:32.285Z","level":"WARN","target":"rust_loadtest::executor","fields":{"step":"GET /dashboard","status":404,"elapsed_ms":312}}
RUST_LOG accepts per-crate filters ā setting hyper=error,reqwest=error suppresses
HTTP client noise and significantly reduces log volume and cost.
Override DNS for specific testing scenarios:
-e RESOLVE_TARGET_ADDR="example.com:192.168.1.50:8080"
Escape commas in header values with backslash:
-e CUSTOM_HEADERS="Keep-Alive:timeout=5\,max=200"
Send JSON data with POST requests:
-e SEND_JSON="true" \
-e JSON_PAYLOAD='{"key":"value","nested":{"data":"here"}}'
bodySize)Stress-test upload endpoints or request-body parsing by sending a synthetic payload of a specified size on every request ā no need to inline large strings in your config.
Supported units: B, KB, MB
scenarios:
- name: "Upload stress test"
weight: 100
steps:
- name: "POST 1MB body"
request:
method: "POST"
path: "/api/upload"
bodySize: "1MB" # generates 1 048 576 random bytes per request
headers:
Content-Type: "application/octet-stream"
assertions:
- type: statusCode
expected: 200
- type: responseTime
max: "5s"
bodySize and body are mutually exclusive ā use one or the other per step.
Combined with JWT auth (multi-step):
scenarios:
- name: "Auth then upload"
weight: 100
steps:
- name: "Login"
request:
method: "POST"
path: "/auth/login"
body: '{"username":"loadtest","password":"secret"}'
headers:
Content-Type: "application/json"
extract:
- type: jsonPath
name: "jwt_token"
jsonPath: "$.token"
assertions:
- type: statusCode
expected: 200
- name: "Upload 512KB"
request:
method: "POST"
path: "/api/upload"
bodySize: "512KB"
headers:
Authorization: "Bearer ${jwt_token}"
Content-Type: "application/octet-stream"
assertions:
- type: statusCode
expected: 200
Every node exposes a lightweight HTTP API for real-time inspection and reconfiguration.
Returns live node status as JSON:
{
"node_id": "node-1",
"region": "us-east",
"node_state": "running",
"rps": 1423.7,
"error_rate_pct": 0.12,
"workers": 25,
"memory_mb": 142.3,
"total_memory_mb": 16384.0,
"cpu_pct": 14.5,
"time_remaining_secs": 3542,
"test_started_at_unix": 1706000000,
"test_duration_secs": 7200,
"test_percent_complete": 50.8,
"current_yaml": "version: \"1.0\"\n..."
}
node_state values: "running" (active test), "standby" (test complete, keeping connections warm), "idle" (no config).
Submit a YAML config to start or reconfigure the test immediately ā no restart required:
curl -X POST http://<node>:8080/config \
-H "Content-Type: application/x-yaml" \
--data-binary @config.yaml
Example YAML config with standby:
version: "1.0"
config:
baseUrl: "https://your-service.com"
workers: 50
duration: "1h"
timeout: "30s"
load:
model: "rps"
target: 500
scenarios:
- name: "Health check"
weight: 100
steps:
- name: "GET /"
request:
method: "GET"
path: "/"
assertions:
- type: statusCode
expected: 200
standby:
workers: 2
rps: 0
When the test duration expires, nodes automatically transition to "standby" state using the standby: block (or startup env-var defaults if no standby: block is present). Standby workers keep connections warm at low (or zero) RPS until a new POST /config arrives.
ā
High Performance: Built in Rust for maximum throughput and minimal overhead
ā
Flexible Load Models: From simple concurrent loads to complex daily traffic patterns
ā
Live Reconfiguration: Update test parameters on the fly via POST /config ā no restart needed
ā
Auto Standby: Nodes automatically switch to warm-standby mode after test completion
ā
Production Ready: Chainguard static images with minimal CVEs
ā
Easy Monitoring: Built-in Prometheus metrics (port 9090) + live health API (port 8080)
ā
Secure: Support for HTTPS, mTLS, and custom authentication
ā
Container Native: Optimized for Docker/Kubernetes/Nomad deployments
ā
Actively Maintained: Regular updates and security patches
This project is open source. See the repository for license details.
Built with ā¤ļø in Rust | Optimized for modern cloud-native deployments
Content type
Image
Digest
sha256:232bc803eā¦
Size
35.1 MB
Last updated
2 days ago
docker pull cbaugus/rust_loadtest