Sometimes you just want a quick number: how many requests per second can this endpoint serve, and how does a config change affect it? wrk and ab (ApacheBench) are small command-line tools for exactly that. They’re perfect for comparing Nginx settings, caching on vs off, or PHP-FPM tuning. For realistic user journeys and thresholds, use k6. See load testing with k6.
Install
sudo apt install -y wrk apache2-utils # apache2-utils provides ab
wrk basics
wrk -t4 -c100 -d30s --latency https://staging.example.com/
-t4: 4 threads (roughly the load generator’s CPU cores);-c100: 100 open connections, kept alive;-d30s: run for 30 seconds;--latency: print the latency distribution.
Example output:
Thread Stats Avg Stdev Max +/- Stdev
Latency 42.10ms 12.31ms 310.00ms 88.12%
Req/Sec 595.20 60.11 800.00 70.00%
Latency Distribution
50% 39.50ms
75% 46.80ms
90% 57.30ms
99% 110.20ms
71280 requests in 30.03s, 1.15GB read
Non-2xx or 3xx responses: 12
Requests/sec: 2373.61
Look at Requests/sec, the p99 latency, and especially non-2xx/3xx responses (errors). High throughput with errors is meaningless.
POST requests and headers with a Lua script
-- post.lua
wrk.method = "POST"
wrk.body = '{"query":"vps"}'
wrk.headers["Content-Type"] = "application/json"
wrk.headers["Authorization"] = "Bearer test-token"
wrk -t2 -c50 -d20s -s post.lua https://staging.example.com/api/search
ApacheBench (ab)
Simpler, single-threaded, and still handy for quick checks:
ab -n 5000 -c 50 -k https://staging.example.com/
-n: total requests;-c: concurrency;-k: keep-alive.- Read “Requests per second”, “Time per request”, “Failed requests”, and the percentage table.
ab’s single thread can become the bottleneck before your server does. Prefer wrk for higher loads.
Get meaningful results
- Don’t run the benchmark on the same server you’re testing. Use another VPS, ideally in the same region (to measure the server, not internet latency), unless you want to include the network.
- Warm up first (caches, OPcache, JIT), and run each test several times.
- Change one thing at a time (gzip on/off, FastCGI cache on/off,
pm.max_children), and compare. - Test realistic URLs: a cached static page gives huge numbers, while an uncached PHP page or search shows the real limits.
- Watch the server during the test (
htop,vmstat 1), to see which resource saturates first. See htop. - Check for rate limiting or WAF blocks (429/403 responses) that make results look bad, or misleadingly good.
Typical comparisons
| Experiment | What you’ll see |
|---|---|
| Static file vs PHP page | Static is often 10–100× faster |
| FastCGI cache on vs off | Large throughput jump for cached pages. See Nginx FastCGI cache |
| OPcache off vs on | Big gain for PHP apps. See PHP OPcache |
| HTTP/1.1 vs keep-alive | Connection reuse matters |
| More PHP-FPM workers | Helps until CPU or RAM saturates. See PHP-FPM tuning |
Ethics and safety
Only benchmark servers you own, or have permission to test. Intense benchmarks against other people’s sites (or through a CDN without permission) are indistinguishable from attacks.
Quick reference
| Task | Command |
|---|---|
| wrk test | wrk -t4 -c100 -d30s --latency URL |
| wrk POST | wrk -s post.lua … |
| ab test | ab -n 5000 -c 50 -k URL |
| Key outputs | Requests/sec, p99 latency, error count |
| Better scenarios | k6 |
Related: web performance testing and Linux benchmark tools.