
Understanding Apache Bench (AB)
Many tools are available to benchmark a web server. The better-known ones are Apache Bench (AB), Siege, JMeter, and Tsung. Although JMeter (https://jmeter.apache.org/) and Tsung (http://tsung.erlang-projects.org/) are very interesting load-testing tools and should be explored when doing more advanced testing in the context of system administration, we will focus on AB and Siege for our development purposes.
AB is included with the Apache web server's development tools and is installed by default in Linux for PHP images that contain PHP binaries. Otherwise, AB can be found in a separate Apache development tools installation package on most Linux distributions. It is important to note that Apache Bench does not support multithreading, which can create problems when running high-concurrency tests.
Also, there are some common pitfalls to avoid when benchmarking. The main ones are:
- Avoid running other resource-hungry applications simultaneously on the computer that is being benchmarked
- Avoid benchmarking remote servers, as the network, especially in concurrency tests, might become the main cause of measured latency
- Avoid testing on web pages that are cached through HTTP accelerators or proxies, as the result will be skewed and will not reveal actual server speed performance
- Do not think that benchmarking and load testing will perfectly represent user interaction with your server, as the results are indicative in nature only
- Be aware that benchmarking results are specific to the hardware architecture being tested and will vary from one computer to the other
For our tests, we will be using Apache Bench’s -k, -l, -c, and -n switches. Here are the definitions of these switches:
- -k enables the KeepAlive feature in order to perform multiple requests in one single HTTP session
- -l disables error reporting when the content lengths vary in size from one response to the other
- -c enables concurrency in order to perform multiple requests at the same time
- -n determines the number of requests to perform in the current benchmarking session
For more information on AB's options, please see the corresponding entry in Apache's documentation (https://httpd.apache.org/docs/2.4/programs/ab.html).
Before launching the benchmark tests, open a new Terminal window and docker exec a new bash Terminal to the container. This way, you will be able to see resource consumption through the top utility. To do so, start by getting the name of your container. It will appear in the list that will be returned by this command:
# docker ps
You will then be able to tap into the container and start watching resource consumption with the following command:
# docker exec -it [name_of_your_container_here] /bin/bash
And, on the container’s newly obtained command line, please run the top command:
# top
Now, launch a benchmark test from within the first Terminal window:
# ab -k -l -c 2 -n 2000 localhost/index.html
You will then get a benchmark test report containing information on the average number of requests per second that the server was able to respond to (Requests per second), the average response time per request (Time per request) and the response time’s standard deviation (Percentage of requests served within a certain time (ms)).
The report should be similar to the following:

The benchmark report shows that Apache is serving about 817 requests per second on average
Now, try a new benchmark test by requesting the index.php file:
# ab -k -l -c 2 -n 2000 localhost/index.php
You will notice that the average number of requests per second has dropped and that the average response time and the standard deviation are higher. In my case, the average has dropped from about 800 to around 300 on my computer, the average response time has passed from 2 milliseconds to 6 milliseconds and the response time’s standard deviation has now gone from 100% of requests being served within 8 milliseconds to 24 milliseconds:

The benchmark report shows that Apache is now serving about 313 requests per second on average
These results allow us to have a general idea of our hardware's performance limits and to determine the different thresholds we would have to deal with when scaling performance of PHP scripts that are generating some dynamic content.
Now, let's dig a little deeper into our web server's performance with Siege, a tool of choice when benchmarking and load testing.