ApacheBench (ab) is a tool for benchmarking your Apache HTTP server. It is designed to give you an idea of the performance that your current Apache installation can give. In particular, it shows you how many requests per second your Apache server is capable of serving. The ab tool comes bundled with the Apache source distribution, and like the Apache web server itself, it's free.

Let's try it. First we create a test script, as shown in Example 9-1.

Example 9-1. simple_test.pl

my $r = shift;
$r->send_http_header('text/plain');
print "Hello\n";

We will simulate 10 users concurrently requesting the file simple_test.pl through http://localhost/perl/simple_test.pl. Each simulated user makes 500 requests. We generate 5,000 requests in total:

panic% ./ab -n 5000 -c 10 http://localhost/perl/simple_test.pl

Server Software:        Apache/1.3.25-dev
Server Hostname:        localhost
Server Port:            8000

Document Path:          /perl/simple_test.pl
Document Length:        6 bytes

Concurrency Level:      10
Time taken for tests:   5.843 seconds
Complete requests:      5000
Failed requests:        0
Broken pipe errors:     0
Total transferred:      810162 bytes
HTML transferred:       30006 bytes
Requests per second:    855.72 [#/sec] (mean)
Time per request:       11.69 [ms] (mean)
Time per request:       1.17 [ms] (mean, across all concurrent requests)
Transfer rate:          138.66 [Kbytes/sec] received

Connnection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0     1    1.4      0    17
Processing:     1    10   12.9      7   208
Waiting:        0     9   13.0      7   208
Total:          1    11   13.1      8   208

Most of the report is not very interesting to us. What we really care about are the Requests per second and Connection Times results:

Requests per second
The number of requests (to our test script) the server was able to serve in one second

Connect and Waiting times
The amount of time it took to establish the connection and get the first bits of a response

Processing time
The server response time—i.e., the time it took for the server to process the request and send a reply

Total time
The sum of the Connect and Processing times

As you can see, the server was able to respond on average to 856 requests per second. On average, it took no time to establish a connection to the server both the client and the server are running on the same machine and 10 milliseconds to process each request. As the code becomes more complicated you will see that the processing time grows while the connection time remains constant. The latter isn't influenced by the code complexity, so when you are working on your code performance, you care only about the processing time. When you are benchmarking the overall service, you are interested in both.

Just for fun, let's benchmark a similar script, shown in Example 9-2, under mod_cgi.

Example 9-2. simple_test_mod_cgi.pl

#!/usr/bin/perl
print "Content-type: text/plain\n\n";
print "Hello\n";

The script is configured as:

ScriptAlias /cgi-bin/ /usr/local/apache/cgi-bin/

panic% /usr/local/apache/bin/ab -n 5000 -c 10 \
http://localhost/cgi-bin/simple_test_mod_cgi.pl

We will show only the results that interest us:

Requests per second:    156.40 [#/sec] (mean)
Time per request:       63.94 [ms] (mean)

Now, when essentially the same script is executed under mod_cgi instead of mod_perl, we get 156 requests per second responded to, not 856.

ApacheBench can generate KeepAlives, GET (default) and POST requests, use Basic Authentication, send cookies and custom HTTP headers. The version of ApacheBench released with Apache version 1.3.20 adds SSL support, generates gnuplot and CSV output for postprocessing, and reports median and standard deviation values.

HTTPD::Bench::ApacheBench, available from CPAN, provides a Perl interface for ab.