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


1 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