Skip to content

Performance-Testing Your Web Application With Bombardier

To figure out if our application can handle a certain load, we need a way to produce that load. That is the purpose of Bombardier, a powerful HTTP benchmarking tool designed to test the performance of web servers. Written in Go, it leverages the fast and efficient fasthttp library, making it an excellent choice to flood a web server with requests.

Usually, our users should behave differently. And while it is important to have realistic scenarios in our performance tests, there is still a place for a tool like Bombardier who just floods the server with requests.

Installation

If you do not have Go and its package manager installed, you best go to the GitHub page and download the latest release. It helps to rename the tool to bombardier.exe and put it in a directory that you can add to the Path. After those steps you should be able to run bombardier from everywhere:

bombardier --version

bombardier version v1.2.6 windows/amd64

If you have a Go installation, you can use this command:

go install github.com/codesenberg/bombardier@latest

Basic usage

The basic syntax for running Bombardier is:

bombardier [<flags>] <url>

Here, <url> is the target URL we want to benchmark and must be set. Bombardier supports a variety of flags to customize our benchmarking tests. If we ignore the flags, it will use 125 concurrent connections and run for 10 seconds.

bombardier http://example.com

Bombarding http://example.com:80 for 10s using 125 connection(s)
[===================================] 10s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec       591.58     677.10    6058.89
  Latency      220.20ms    86.77ms   822.86ms
  HTTP codes:
    1xx - 0, 2xx - 5784, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:     0.90MB/s

Each connection fires a request and then waits for a response. When the response comes back, it checks the status code and sends the next one. Should nothing come back, it waits for the specified timeout, marks the request as a failure and sends the next one.

The reporting we get contains a basic distribution of requests and the duration. The first check we should do is look at the HTTP status codes. If everything worked, we should only get 2xx status codes back. Otherwise, we know right there that something went wrong.

Main options

From all the flags Bombardier offers, these are the ones that I use the most:

Flag Meaning
-c, --connections Specifies the maximum number of concurrent connections.
-d, --duration Defines the duration of the test (e.g., 10s for 10 seconds)
-H, --header Adds custom HTTP headers to the requests
--http1 or --http2: Forces the use of HTTP/1.x or HTTP/2.0 clients
-l, --latencies Print latency statistics

These options provide flexibility and enable us to simulate various real-world scenarios and stress test our web applications effectively. Nevertheless, read the documentation for the other flags that may help you with your use cases.

Output and reporting

Bombardier provides detailed output to help you analyse the performance of your web server. The default output includes statistics such as:

  • Requests per second: The rate at which requests get processed. Just ignore the Max column – it is often a massive exaggeration and happens with fractions of seconds that are extrapolated.
  • Latency: The time taken for requests to be completely processed.
  • HTTP codes: The distribution of HTTP response codes it received.
  • Throughput: The amount of data transferred per second.

You can customize the output format using the -o or --format flag, which supports plain text and JSON formats. This flexibility allows you to integrate Bombardier’s results into your existing monitoring and reporting systems.

Latency distribution

When we use the -l or --latencies flag, we get a detailed latency statistic. This helps us to better understand the distribution of the response times:

bombardier -l http://example.com

Bombarding http://example.com:80 for 10s using 125 connection(s)
[===================================] 10s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec       303.96     417.49    3179.21
  Latency      555.39ms      0.96s      5.50s
  Latency Distribution
     50%   255.79ms
     75%   434.70ms
     90%      0.96s
     95%      1.86s
     99%      5.37s
  HTTP codes:
    1xx - 0, 2xx - 3092, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:   359.14KB/s

The interesting part of the latency distribution are the percentage values, but what does that mean? These values are percentiles, that you often find written as P50, P75, P90, P95, and P99 when there is no % sign.

To get the percentiles, we take all requests, order them by duration and then see how many values we have below a certain threshold. The P50 stands for the median and is the value in the middle of our results. It is named P50 because 50% of the values are below (and 50% are above). For P90 we know that 90% of the values are below this threshold and10% are above.

For web applications we are most often interested in P95 and P99. That covers the widest part of the users yet excludes the worst outliers.

When we look at the output above, we see that the median (P50) value for the requests was at 255ms, while 95% of our requests took less than 1.86 seconds. This shows us that there is a large variety in request duration and that for a lot of our users the application will feel a bit slow.

Limitations

As addressed in the introduction, Bombardier only floods a single URL with requests at a time. That should not be a realistic scenario for your users. Nevertheless, that does not mean it cannot help us with performance testing.

Flooding an endpoint with requests is a good test to see how that part of the application behaves. If you hit your start page with Bombardier and it breaks right away, the journey of your users will also be cut short – then when the start page fails, there will be no links to go further.

Next

Bombardier is a versatile and powerful tool for HTTP benchmarking, even when it only floods a single endpoint at a time. With its customisations you can make it fit your use-case and gain valuable insights into your web server’s performance.

Now that we have a first tool to measure our application, it is time to make sure we do not waste our time with the wrong settings inside the application we want to test.