How to Install and Use oha on Linux for Interactive HTTP Load Testing and Benchmarking

Benchmarking web applications and HTTP APIs under sustained concurrency is essential for detecting bottlenecks before traffic spikes reach production. While legacy tools like ApacheBench (ab) and wrk provide raw throughput metrics, they lack interactive terminal visualisations. oha (written in Rust) is a modern HTTP load generator that renders real-time ASCII response time histograms, throughput gauges, and detailed latency percentiles directly within your terminal session.

This tutorial explains how to install oha on Linux, execute concurrent load tests against REST APIs and web servers, customise request payloads and authentication headers, and interpret real-time statistical distributions.

Installing oha on Linux Distributions

oha is distributed as a standalone, statically linked binary and is packaged across multiple Linux package managers.

Method 1: Installing via Cargo (Recommended for Rust Users)

If you have the Rust toolchain installed, build and install the latest release directly via Cargo:

cargo install oha

Method 2: Installing via Snap or Homebrew

On Ubuntu and Debian systems with Snap enabled:

sudo snap install oha

On systems running Homebrew on Linux:

brew install oha

Method 3: Downloading Pre-Compiled GitHub Release Binaries

To install oha manually without dependencies, pull the official pre-compiled release from GitHub:

# Download the latest x86_64 Linux release
curl -L https://github.com/hatoo/oha/releases/latest/download/oha-linux-amd64 -o /tmp/oha

# Make executable and relocate to system path
chmod +x /tmp/oha
sudo mv /tmp/oha /usr/local/bin/oha

# Verify installation
oha --version

Running a Basic HTTP Load Test

By default, executing oha with a target URL sends 200 total requests across 50 concurrent connections.

oha https://api.example.com/health

As the benchmark executes, oha takes over the terminal window, displaying an animated progress bar, queries per second (QPS), and a dynamic ASCII latency histogram updating in milliseconds.

Ethical Testing Notice

Only execute load tests against servers, APIs, and cloud infrastructure you personally own or have explicit written authorisation to test. Unauthorised stress testing can trigger Web Application Firewalls (WAFs), IP bans, and violate hosting service agreements.

Customising Concurrency, Duration, and Rate Limits

Production benchmarks require fine-tuning volume, connection counts, and request throttling to simulate realistic user behaviours.

Flag / Option Syntax Example Benchmark Purpose
-n <number> oha -n 10000 https://target Total number of HTTP requests to send across the entire test run.
-c <number> oha -c 100 https://target Number of parallel worker connections to keep active simultaneously.
-z <duration> oha -z 30s https://target Runs the load test for a specific time limit (e.g. 30s, 2m, 1h).
-q <number> oha -q 500 https://target Throttles request rate to a fixed Queries Per Second (QPS) ceiling.
–http2 oha --http2 https://target Forces multiplexed HTTP/2 protocol evaluation.

To run a 60-second endurance stress test with 200 concurrent workers capped at 1,000 queries per second:

oha -z 60s -c 200 -q 1000 https://api.example.com/v1/products

Benchmarking POST Endpoints with JSON Payloads and Auth Headers

Modern microservices require testing authenticated write endpoints. You can supply custom HTTP request methods, authentication headers, and JSON body payloads.

oha -m POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer secret-token-xyz" \
  -d '{"searchQuery": "database clustering", "limit": 25}' \
  -n 5000 \
  -c 75 \
  https://api.example.com/v1/search

If your payload is stored in a local file, pass it using standard shell input:

oha -m POST \
  -H "Content-Type: application/json" \
  -D payload.json \
  https://api.example.com/v1/orders

Exporting Load Test Results to JSON for CI/CD Pipelines

While the real-time TUI is ideal for manual terminal analysis, automated CI/CD performance regression gates require machine-readable outputs. Disable the TUI and dump structured JSON metrics using the --no-tui and --json flags:

oha --no-tui --json -n 2000 -c 50 https://api.example.com/status > benchmark_report.json

You can then parse critical latency percentiles (such as p50, p90, p99) using jq:

cat benchmark_report.json | jq '.latencyPercentiles'

Troubleshooting Common oha Benchmark Errors

If your stress test fails or yields misleading data, review these system-level constraints:

  • Too Many Open Files (OS Error 24): High concurrency benchmarks open hundreds of simultaneous TCP sockets. If oha crashes with socket exhaustion errors, increase your system user file descriptor ceiling:
    ulimit -n 65535
  • Connection Refused or Timeouts: When testing against local microservices running on localhost, ensure your server’s connection backlog queue is configured to handle burst traffic. On Linux, review sysctl net.core.somaxconn.
  • Distorted Latencies Due to Client CPU Saturation: If your client machine runs at 100% CPU utilisation during the test, oha’s internal scheduling delays can artificially inflate reported response times. Monitor system resource load using htop during execution.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.