HTTPRunner is a powerful tool for load testing HTTP requests, developed in Go. It allows developers and testers to effectively assess the performance of web applications, identify bottlenecks, and ensure stability under high traffic.
- Load Generation — create and send a multitude of HTTP requests to simulate real traffic.
- Custom Scenarios — define testing scenarios for various types of requests and parameters via YAML.
- Performance Reports — response times (average, p50/p90/p95/p99, min, max) plus throughput in requests/sec and bytes/sec.
- Latency Distribution — a text histogram of response times so you can see the shape of the distribution, not just percentiles.
- Latency Breakdown — average DNS, TCP connect, TLS handshake and time-to-first-byte per request, plus connection-reuse rate (HTTP/2 enabled).
- CI Gating —
-fail-ifexits non-zero when a latency or success-rate budget is violated. - Success Rate Calculation — the percentage of successful (2xx) responses, with a per-status-code breakdown.
- Config Validation — invalid values (e.g.
concurrency < 1, negativerate/duration) fail fast with a clear message. - Graceful Interrupt — Ctrl-C finishes in-flight requests and prints a partial report; a second Ctrl-C forces an immediate exit.
# Install (Linux / macOS)
curl -fsSL https://raw.githubusercontent.com/idesyatov/http-runner/master/install.sh | sh
# Single GET request
http-runner -url "https://example.com"
# 100 requests with 50 concurrent workers
http-runner -url "https://example.com" -count 100 -concurrency 50
# POST with a JSON body
http-runner -method POST -url "https://example.com/api" -count 10 -data '{"key":"value"}'
# Run for 30s capped at 50 req/s, machine-readable output
http-runner -url "https://example.com" -duration 30s -rate 50 -output jsonRun
http-runner -helpfor the full list of flags.
Installation (script · go install · prebuilt binaries)
Download the latest release binary and install it to /usr/local/bin:
curl -fsSL https://raw.githubusercontent.com/idesyatov/http-runner/master/install.sh | shThe script detects your OS and architecture, fetches the latest release, verifies the SHA-256 checksum, and installs the binary. You can override the defaults:
# Pin a specific version and/or change the install directory:
curl -fsSL https://raw.githubusercontent.com/idesyatov/http-runner/master/install.sh | VERSION=v1.6.0 BINDIR=$HOME/.local/bin shPrefer to review before running? Download install.sh, read it, then run sh install.sh.
go install github.com/idesyatov/http-runner@latestDownload an archive for your platform from the
Releases page, or build it
yourself with make build.
Command-line flags
-method: HTTP method to use (e.g., GET, POST). Default is GET.-url: Target URL for the requests. This flag is required.-count: Number of requests to send. Default is 1.-verbose: Enable verbose output for detailed logging.-concurrency: Number of concurrent requests to send. Default is 10.-headers: Comma-separated list of headers in the format key:value.-data: JSON body to send with the request. Accepts any valid JSON (nested objects, arrays, numbers). Pass inline JSON, or@path/to/file.jsonto read the body from a file (curl style).-timeout: Per-request timeout (e.g.10s,500ms). Default is5s.-duration: Run the load for this wall-clock duration instead of-count(e.g.30s).-rate: Target requests per second. Default is0(unlimited).-output: Output format:text(default) orjson.-insecure: Skip TLS certificate verification.-redirects: Follow HTTP redirects. Default istrue(use-redirects=falseto disable).-fail-if: Comma-separated pass/fail thresholds; the process exits non-zero if any holds. Handy for gating CI. Metrics:p50p90p95p99avgminmaxttfb(durations, e.g.500ms),success(percent),rps(float),errors(count). Operators:><>=<===!=. Example:-fail-if 'p99>500ms,success<99'.-config-file: Path to the configuration file in YAML format. If this flag is provided, the per-endpoint flags are ignored (-output,-insecure,-redirects,-fail-ifstill apply).-version: Show the application version and exit.
Examples (CLI)
# To get information on all flags:
http-runner -help
# To send a single GET request to a specified URL:
http-runner -url "https://example.com"
# To send 100 GET requests to a specified URL:
http-runner -url "https://example.com" -count 100
# To send 10 POST requests to a specified URL with JSON data:
http-runner -method "POST" \
-url "https://example.com/api" \
-count 10 \
-data '{"key1":"value1", "key2":"value2"}'
# To send a nested JSON body:
http-runner -method "POST" \
-url "https://example.com/api" \
-data '{"user":{"id":1,"roles":["admin","ops"]}}'
# To read the JSON body from a file (curl style):
http-runner -method "POST" \
-url "https://example.com/api" \
-data @payload.json
# To enable verbose output while sending requests:
http-runner -url "https://example.com" \
-count 10 \
-verbose
# To send 50 concurrent requests to a specified URL:
http-runner -url "https://example.com" \
-count 50 \
-concurrency 50
# To send a single GET request to a specified URL with custom headers:
http-runner -url "https://example.com/api" \
-headers "Authorization: Bearer your_token, Content-Type: application/json"
# To run for 30s capped at 50 req/s with machine-readable output:
http-runner -url "https://example.com" \
-duration 30s \
-rate 50 \
-output json
# To gate CI on a latency/success budget (exit non-zero if breached):
http-runner -url "https://example.com" \
-count 500 \
-concurrency 50 \
-fail-if "p99>500ms,success<99"
# To load configuration from a YAML file:
http-runner -config-file "config.yaml"Configuration file (YAML, all parameters)
Pass -config-file path.yml; the per-endpoint flags are then ignored, while the global flags -output, -insecure, -redirects and -fail-if still apply.
# Configuration file for http-runner, demonstrating all possible parameters
endpoints:
- url: "https://example.com/api" # (Required) Target URL for requests.
method: "POST" # (Optional, default: GET) HTTP method for the request.
headers: # (Optional) Headers for the request in key:value format.
Authorization: "Bearer your_token"
Content-Type: "application/json"
data: # (Optional) Request body. Any JSON shape, including nested objects and arrays.
key1: "value1"
user:
id: 1
roles: ["admin", "ops"]
count: 5 # (Optional, default: 1) Number of requests to send.
concurrency: 3 # (Optional, default: 10) Number of concurrent requests.
timeout: "10s" # (Optional, default: 5s) Per-request timeout.
duration: "30s" # (Optional) Run for this wall-clock time instead of count.
rate: 50 # (Optional, default: 0) Target requests per second (0 = unlimited).
verbose: true # (Optional) Enables detailed output for logging.
- url: "https://example.org" # (Optional) Second example with a different URL.
method: "GET" # (Optional) Default GET method.
headers: # (Optional) Headers for the request.
Accept: "application/json"
count: 10 # (Optional, default: 1) Number of requests.
concurrency: 5 # (Optional, default: 10) Number of concurrent requests.
verbose: false # (Optional) Disables detailed output.
- url: "https://api.example.com/data" # (Optional) Third example URL.
method: "PUT" # (Optional) PUT method.
headers: # (Optional) Headers for the request.
Content-Type: "application/x-www-form-urlencoded"
data: # (Optional) Data for updating.
name: "Item"
value: "UpdatedValue"
count: 1 # (Optional, default: 1) Only one request.
concurrency: 1 # (Optional, default: 10) One request at a time.
verbose: true # (Optional) Enables detailed output.