How to load-test web server with ab (ApacheBench)

ab is a benchmarking tool for web server that normally comes standard with Apache installation. It's used for load-testing your web server and produce useful metrics such as the number of requests per second that the server is able to serve.

ab could be used to benchmark any web server including Apache and NGINX

The basic way of the load-testing with ab is by specifying the total number of requests to test the web server against and the concurrency level or the number of request to be sent in parallel.

$ ab -n <number_of_request> -c <concurrency> <url>

Sample output of the command is as the following;

$ ab -n 1000 -c 10
This is ApacheBench, Version 2.3 <$Revision: 1826891 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
Licensed to The Apache Software Foundation,

Benchmarking (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        Apache/2.4.33
Server Hostname:
Server Port:            443

Document Path:          /
Document Length:        12906 bytes

Concurrency Level:      10
Time taken for tests:   19.070 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      13410000 bytes
HTML transferred:       12906000 bytes
Requests per second:    52.44 [#/sec] (mean)
Time per request:       190.704 [ms] (mean)
Time per request:       19.070 [ms] (mean, across all concurrent requests)
Transfer rate:          686.70 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       1
Processing:    73  190  41.2    186     348
Waiting:       72  188  41.2    185     346
Total:         73  190  41.2    186     348

Percentage of the requests served within a certain time (ms)
  50%    186
  66%    207
  75%    218
  80%    226
  90%    244
  95%    257
  98%    272
  99%    305
 100%    348 (longest request)

This sends a total of 1000 requests to the web server with 10 being sent concurrently

Some of the more important results are Requests per second and Time per request.

Other commonly used options for testing are -k which is to enable KeepAlive mode and reducing network overhead by sharing a single HTTP session. You can see all the other available options by using -h such as the following;

$ ab -h
Usage: ab [options] [http[s]://]hostname[:port]/path
Options are:
    -n requests     Number of requests to perform
    -c concurrency  Number of multiple requests to make at a time
    -t timelimit    Seconds to max. to spend on benchmarking
                    This implies -n 50000
    -s timeout      Seconds to max. wait for each response
                    Default is 30 seconds
    -b windowsize   Size of TCP send/receive buffer, in bytes
    -B address      Address to bind to when making outgoing connections
    -p postfile     File containing data to POST. Remember also to set -T
    -u putfile      File containing data to PUT. Remember also to set -T
    -T content-type Content-type header to use for POST/PUT data, eg.
                    Default is 'text/plain'
    -v verbosity    How much troubleshooting info to print
    -w              Print out results in HTML tables
    -i              Use HEAD instead of GET
    -x attributes   String to insert as table attributes
    -y attributes   String to insert as tr attributes
    -z attributes   String to insert as td or th attributes
    -C attribute    Add cookie, eg. 'Apache=1234'. (repeatable)
    -H attribute    Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
                    Inserted after all normal header lines. (repeatable)
    -A attribute    Add Basic WWW Authentication, the attributes
                    are a colon separated username and password.
    -P attribute    Add Basic Proxy Authentication, the attributes
                    are a colon separated username and password.
    -X proxy:port   Proxyserver and port number to use
    -V              Print version number and exit
    -k              Use HTTP KeepAlive feature
    -d              Do not show percentiles served table.
    -S              Do not show confidence estimators and warnings.
    -q              Do not show progress when doing more than 150 requests
    -l              Accept variable document length (use this for dynamic pages)
    -g filename     Output collected data to gnuplot format file.
    -e filename     Output CSV file with percentages served
    -r              Don't exit on socket receive errors.
    -m method       Method name
    -h              Display usage information (this message)
    -I              Disable TLS Server Name Indication (SNI) extension
    -Z ciphersuite  Specify SSL/TLS cipher suite (See openssl ciphers)
    -f protocol     Specify SSL/TLS protocol
                    (SSL3, TLS1, TLS1.1, TLS1.2 or ALL)

From here you can tweak your web server settings and redo the test iteratively until you get satisfactory numbers.

Here are some note and tips when using ab to load test your web server;

  1. This is by no mean mimic real world usage. Other tools such as Apache's JMeter might be more suitable for that.
  2. ab should not be run on the same machine as the web server. ab itself is resource intensive, thus doing so will negatively impact the web server's performance and skew the test result.
  3. There are various factors that could the server's performance. It's best to run multiple tests and average the result.