ab (ApacheBench): -n Requests, -c Concurrency
ab -n sends a fixed number of requests at -c concurrency to one URL and prints requests/sec plus the time-per-request percentile table.
ApacheBench ships with Apache and is on almost every runner, which makes it a quick smoke-load tool. It is request-count based (-n), not duration based, and it is picky about the URL path.
What it does
ab issues -n total requests with up to -c in flight at once against a single URL and reports requests/sec, mean/median time per request, and a percentile table (50%, 90%, 99%, 100%). With -t it runs for a time budget instead of a fixed count.
Common usage
# 10000 requests, 100 concurrent
ab -n 10000 -c 100 http://localhost:8080/
# keep-alive, and POST a JSON body
ab -n 5000 -c 50 -k -p body.json -T application/json http://localhost:8080/apiOptions
| Flag | What it does |
|---|---|
| -n <N> | Total number of requests to perform |
| -c <N> | Number of concurrent requests |
| -t <sec> | Max seconds to spend (implies a large -n) |
| -k | Use HTTP KeepAlive |
| -p <file> -T <type> | POST the file with the given content type |
| -H <header> | Add a request header |
| -l | Accept variable response length (do not count as errors) |
In CI
ab exits 0 even under failures, so parse the output: fail the step if Failed requests is nonzero or if the 99% row exceeds your latency budget. If the body length varies per response, add -l so ab does not flag every reply as a length mismatch failure.
Common errors in CI
ab: Invalid URL almost always means you left off the trailing path; ab requires a full URL including at least / (use http://host:8080/, not http://host:8080). apr_socket_recv: Connection refused (111) means the server is not up yet. ab: command not found needs apt-get install -y apache2-utils (Debian/Ubuntu) or apk add apache2-utils (Alpine). Non-2xx responses show up under Non-2xx responses: rather than Failed requests, so check both.