Understanding Apache Benchmark (ab) Output: Decoding “Time per request” Metrics for Concurrent Load Testing


23 views

When running Apache Benchmark (ab), the two "Time per request" values often cause confusion. Let's break down what each represents:

Time per request:       109537.505 [ms] (mean)
Time per request:       109.538 [ms] (mean, across all concurrent requests)

The first value is calculated as:

total_time = (time_for_entire_test)
mean_time_per_request = total_time / number_of_requests

The second value is derived from:

mean_time_across_concurrency = mean_time_per_request / concurrency_level

Consider this test command and its output:

ab -n 1000 -c 10 http://test.server/api

Server Software:        Apache
Time taken for tests:   5.477 seconds
Time per request:       5.477 [ms] (mean)
Time per request:       0.548 [ms] (mean, across all concurrent requests)

The first metric shows system throughput (how long the test took overall), while the second reveals individual request latency under concurrency. For instance:

# Bad performance shows divergence
ab -n 100 -c 100 http://slow.server/api
Time per request:       2500.000 [ms] (mean)
Time per request:       25.000 [ms] (mean, across all concurrent requests)

# Good performance shows closer values  
ab -n 100 -c 10 http://fast.server/api
Time per request:       50.000 [ms] (mean)
Time per request:       5.000 [ms] (mean, across all concurrent requests)

Complete picture requires understanding all metrics:

Requests per second:    182.56 [#/sec] (mean)
Percentage of the requests served within a certain time (ms)
  50%     98
  66%     102
  75%     105
  80%     108
  90%     112
  95%     118
  98%     123
  99%     126
 100%     135 (longest request)

When running Apache Bench (ab), many developers get puzzled by these two lines:

Time per request:       109537.505 [ms] (mean)
Time per request:       109.538 [ms] (mean, across all concurrent requests)

Let's break down why these numbers differ by 100x:

  • The first value (109537.505ms) is the server-side processing time per individual request
  • The second value (109.538ms) represents the client-perceived latency when requests are made concurrently

Consider this test command:

ab -n 1000 -c 10 http://example.com/

Here's how to calculate both values:

Total time = 109.538ms * 1000 requests = ~109.538 seconds
Individual request time = Total time / concurrency = 109.538 / 10 = ~10.954ms

Understanding these metrics helps you:

  1. Identify server bottlenecks (first metric)
  2. Measure real-world user experience (second metric)
  3. Properly scale your infrastructure

Watch out for these mistakes when interpreting ab results:

# Bad practice - testing with default single connection
ab -n 100 http://example.com/

# Better approach - simulate real traffic
ab -n 1000 -c 50 http://example.com/api

For more accurate results, consider these factors:

  • Network latency between client and server
  • Client machine resources
  • Server keep-alive settings

While ab is great for quick tests, for complex scenarios consider:

Tool Best For
wrk High concurrency
JMeter Complex test scenarios
k6 Cloud-based testing