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.

  • Performance
  • Testing
  • Nginx