Fast cross-platform HTTP benchmarking tool written in Go

bombardier Build Status Go Report Card GoDoc Coverage

bombardier is a HTTP(S) benchmarking tool. It is written in Go programming language and uses excellent fasthttp instead of Go's default http library, because of its lightning fast performance.

With bombardier v1.1 and higher you can now use net/http client if you need to test HTTP/2.x services or want to use a more RFC-compliant HTTP client.

Tested on go1.8 and higher.

Installation

You can grab binaries in the releases section. Alternatively, to get latest and greatest run:

go get -u github.com/codesenberg/bombardier

Usage

bombardier [<flags>] <url>

For a more detailed information about flags consult GoDoc.

Known issues

AFAIK, it's impossible to pass Host header correctly with fasthttp, you can use net/http(--http1/--http2 flags) to workaround this issue.

Examples

Example of running bombardier against this server:

> bombardier -c 125 -n 10000000 http://localhost:8080
Bombarding http://localhost:8080 with 10000000 requests using 125 connections
 10000000 / 10000000 [============================================] 100.00% 37s Done!
Statistics        Avg      Stdev        Max
  Reqs/sec    264560.00   10733.06     268434
  Latency      471.00us   522.34us    51.00ms
  HTTP codes:
    1xx - 0, 2xx - 10000000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:   292.92MB/s

Or, against a realworld server(with latency distribution):

> bombardier -c 200 -d 10s -l http://ya.ru
Bombarding http://ya.ru for 10s using 200 connections
[=========================================================================] 10s Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      6607.00     524.56       7109
  Latency       29.86ms     5.36ms   305.02ms
  Latency Distribution
     50%    28.00ms
     75%    32.00ms
     90%    34.00ms
     99%    48.00ms
  HTTP codes:
    1xx - 0, 2xx - 0, 3xx - 66561, 4xx - 0, 5xx - 0
    others - 5
  Errors:
    dialing to the given TCP address timed out - 5
  Throughput:     3.06MB/s
Owner
Максим Федосеев
Максим Федосеев
Comments
  • feature: Prometheus node_exporter compatible output

    feature: Prometheus node_exporter compatible output

    The output produced by bombardier cannot be consumed by Prometheus.

    It would be nice to have metrics like this:

    image

    Prometheus' node_exporter has textfile collector. The collector scans directory for .prom files and adds the metrics found in the file to its own metrics set.

    This way, I can run bombardier every minute, output results to bombardier.prom file and the metrics will be picked up by Prometheus server.

    I would like to come up with a number of metrics and have an option to output results as a Prometheus metric.

    For example, the following output:

    Statistics        Avg      Stdev        Max
      Reqs/sec      6607.00     524.56       7109
      Latency       29.86ms     5.36ms   305.02ms
    

    would result in the following metrics:

    • bombardier_http_request_rate_avg
    • bombardier_http_request_rate_max
    • bombardier_http_request_rate_stdev
    • bombardier_http_latency_avg
    • bombardier_http_latency_stdev
    • bombardier_http_latency_max

    Each metric could have one or more labels associated with it.

    For example, the following command:

    bombardier -c 200 -d 10s -l http://ya.ru
    

    would result in the following metrics:

    conn: 200
    duration: 10
    url: http://ya.ru
    

    Further, it would be helpful to output UUID associated with each test.

  • i/o timeout with fasthttp client

    i/o timeout with fasthttp client

    There are problems connecting with envoy proxy

    What version of bombardier are you using?

    bombardier version v1.2

    What operating system and processor architecture are you using (if relevant)?

    linux/amd64

    What did you do?

    docker run --rm -d -p 10000:10000 envoyproxy/envoy:latest

    $ curl -I http://localhost:10000
    HTTP/1.1 200 OK
    ...
    
    $ bombardier http://localhost:10000
    Statistics        Avg      Stdev        Max
      Reqs/sec         9.45     210.84    4724.01
      Latency        10.01s     3.58ms     10.01s
      HTTP codes:
        1xx - 0, 2xx - 0, 3xx - 0, 4xx - 0, 5xx - 0
        others - 125
      Errors:
        read tcp [::1]:9050->[::1]:10000: i/o timeout - 1
        read tcp [::1]:9248->[::1]:10000: i/o timeout - 1
        read tcp [::1]:9258->[::1]:10000: i/o timeout - 1
        read tcp [::1]:9004->[::1]:10000: i/o timeout - 1
    ...
    

    With net/http client all ok

    $ bombardier --http1 http://localhost:10000
    Statistics        Avg      Stdev        Max
      Reqs/sec       335.52     128.07     750.00
      Latency      365.64ms    86.23ms   565.60ms
      HTTP codes:
        1xx - 0, 2xx - 0, 3xx - 3479, 4xx - 0, 5xx - 0
        others - 0
      Throughput:   308.91KB/s
    

    What you expected to happen?

    A typical http connection

    What actually happened?

    read tcp [::1]:9004->[::1]:10000: i/o timeout - 1

  • multipart/form-data ?

    multipart/form-data ?

    Hi,

    I'm trying to load a test a binary upload endpoint using multipart/form-data and was wondering if it's possible to make bombardier handle this type of request?

    thanks!

  • go get -u -v github.com/codesenberg/bombardier errror

    go get -u -v github.com/codesenberg/bombardier errror

    When i run this command "go get -u -v github.com/codesenberg/bombardier" i get error

    package github.com/codesenberg/bombardier/vendor/golang.org/x/net/http2:
    vendor/golang.org/x/net/http2/pipe.go:1:1: expected 'package', found 'EOF'
    

    Please give me a solution, thanks you so much| [From MacOS]

  • Panic in histogram.go:53 using 1.1.1 on win/386

    Panic in histogram.go:53 using 1.1.1 on win/386

    What version of bombardier are you using?

    bombardier version v1.1.1 windows/386

    What operating system and processor architecture are you using (if relevant)?

    windows/386

    What did you do?

    bombardier -d 1m http://localhost:55555/test/00660066

    What you expected to happen?

    I expected it to run for 1 minute.

    What actually happened?

    Bombarding http://localhost:55555/test/00660066 for 1m0s using 125 connections
    [============>------------------------------------------------------------] 50sp
    anic: runtime error: index out of range
    
    goroutine 167 [running]:
    codesenberg/bombardier/vendor/github.com/codesenberg/concurrent/float64/histogra
    m.(*Histogram).getShardFor(0x31372710, 0xe498c1cd, 0x4088ffa5, 0xfa894f1a)
            C:/Users/frei/Documents/Go/Workspaces/Default/src/codesenberg/bombardier
    /vendor/github.com/codesenberg/concurrent/float64/histogram/histogram.go:53 +0x5
    c
    codesenberg/bombardier/vendor/github.com/codesenberg/concurrent/float64/histogra
    m.(*Histogram).Add(0x31372710, 0xe498c1cd, 0x4088ffa5, 0x1, 0x0)
            C:/Users/frei/Documents/Go/Workspaces/Default/src/codesenberg/bombardier
    /vendor/github.com/codesenberg/concurrent/float64/histogram/histogram.go:64 +0x3
    1
    codesenberg/bombardier/vendor/github.com/codesenberg/concurrent/float64/histogra
    m.(*Histogram).Increment(0x31372710, 0xe498c1cd, 0x4088ffa5)
            C:/Users/frei/Documents/Go/Workspaces/Default/src/codesenberg/bombardier
    /vendor/github.com/codesenberg/concurrent/float64/histogram/histogram.go:58 +0x3
    d
    main.(*bombardier).recordRps(0x31270fc0)
            C:/Users/frei/Documents/Go/Workspaces/Default/src/codesenberg/bombardier
    /bombardier.go:259 +0x1b8
    main.(*bombardier).rateMeter(0x31270fc0)
            C:/Users/frei/Documents/Go/Workspaces/Default/src/codesenberg/bombardier
    /bombardier.go:239 +0xa5
    created by main.(*bombardier).bombard
            C:/Users/frei/Documents/Go/Workspaces/Default/src/codesenberg/bombardier
    /bombardier.go:273 +0xfc
    

    This happens with no rhyme or reason I can detect. Sometimes it panics with -d 1s, sometimes it works for 10s with no issues.

  • Can I send a request with

    Can I send a request with "Content-Type: application/x-www-form-urlencoded; charset=UTF-8"?

    Hi,

    I want to do load test for a POST request that the Content-Type: application/x-www-form-urlencoded; charset=UTF-8.

    and the form data is: action=get_data&number=1234

    is it possible to do it with bombadier?

    Thanks.

  • Include how to set headers in the readme

    Include how to set headers in the readme

    Could you include an example where you use http headers ?

    Tried to set with the following

    bombardier -c 2 -d 2s -H 'Content-Type: application/json' -data '{"key": "value"}' -m POST http://localhost:5001
    

    but when I examined the target I'm getting the following content type value

    application/x-www-form-urlencoded application/json application/json
    

    How can you set multiple headers ?

    Thanks Pat

  • Bombardier checks hostname plausibility when it shouldn't

    Bombardier checks hostname plausibility when it shouldn't

    What version of bombardier are you using?

    in case you've built bombardier yourself or version obtained by

    # bombardier --version
    bombardier version v1.2 linux/amd64
    

    in case you are using binaries.

    What operating system and processor architecture are you using (if relevant)?

    linux/amd64

    What did you do?

    # bombardier http://www-service/
    host www-service: invalid host
    

    Describe steps that can be used to reproduce the error.

    What you expected to happen?

    Bombardier would try to resolve www-service which is a valid DNS name in my setup.

    What actually happened?

    Bombardier quits with the message:

    host www-service: invalid host
    

    I couldn't find the error message in the source code, so I think it is some vendor bug trying to validate domains even though they shouldn't. www-service.default which is also a valid DNS name works fine.

  • compare with python requests

    compare with python requests

    Why the latency result of the bom is different with the python requests package?

    bom average 1.58ms, requests 250ms

    bom result:

    Statistics        Avg      Stdev        Max
      Reqs/sec      6286.72     460.12    7012.96
      Latency        1.58ms   349.64us    26.34ms
      HTTP codes:
        1xx - 0, 2xx - 63013, 3xx - 0, 4xx - 0, 5xx - 0
        others - 0
      Throughput:     2.13MB/s
    
    python requests package:
    >>> import requests
    >>> url = "http://10.143.192.105:9362/hotrizon/GetScore?m2=000029da81eafcfcdbde82d6bd2d2&qid=29957933"
    >>> import time
    >>> def func():
    ...     t = time.time()
    ...     requests.get(url)
    ...     print time.time() -t 
    ... 
    >>> func()
    0.376302957535
    >>> func()
    0.293756961823
    >>> func()
    0.292520046234
    >>> func()
    0.291940927505
    >>> func()
    0.291563034058
    >>> func()
    0.292473077774
    
  • Update README.md

    Update README.md

    I get the following installing via the readme method

    go get: installing executables with 'go get' in module mode is deprecated.
            Use 'go install pkg@version' instead.
            For more information, see https://golang.org/doc/go-get-install-deprecation
            or run 'go help get' or 'go help install'.
    
  • Not all request flags are available.

    Not all request flags are available.

    First of all, thank you very much @codesenberg for this an amazing and useful project!

    What version of bombardier are you using?

    bombardier --version
    bombardier version v1.1.2 windows/386
    

    What did you do?

    bombardier --help
    

    or

    bombardier -c 1 -r 1 -d 1s -q -l http://ya.ru --help
    unknown short flag '-q'
    

    or

    bombardier -c 1 -r 1 -d 1s --no-print -l http://ya.ru --help
    unknown long flag '--no-print'
    

    What you expected to happen?

    As it is in the Docs.

    usage: bombardier [<flags>] <url>
    
    Fast cross-platform HTTP benchmarking tool
    
    Flags:
          --help                  Show context-sensitive help (also try --help-long
                                  and --help-man).
          --version               Show application version.
      -c, --connections=125       Maximum number of concurrent connections
      -t, --timeout=2s            Socket/request timeout
      -l, --latencies             Print latency statistics
      -m, --method=GET            Request method
      -b, --body=""               Request body
      -f, --body-file=""          File to use as request body
      -s, --stream                Specify whether to stream body using chunked
                                  transfer encoding or to serve it from memory
          --cert=""               Path to the client's TLS Certificate
          --key=""                Path to the client's TLS Certificate Private Key
      -k, --insecure              Controls whether a client verifies the server's
                                  certificate chain and host name
      -H, --header="K: V" ...     HTTP headers to use(can be repeated)
      -n, --requests=[pos. int.]  Number of requests
      -d, --duration=10s          Duration of test
      -r, --rate=[pos. int.]      Rate limit in requests per second
          --fasthttp              Use fasthttp client
          --http1                 Use net/http client with forced HTTP/1.x
          --http2                 Use net/http client with enabled HTTP/2.0
      -p, --print=<spec>          Specifies what to output. Comma-separated list of
                                  values 'intro' (short: 'i'), 'progress' (short:
                                  'p'), 'result' (short: 'r'). Examples:
      
                                    * i,p,r (prints everything)
                                    * intro,result (intro & result)
                                    * r (result only)
                                    * result (same as above)
      -q, --no-print              Don't output anything
      -o, --format=<spec>         Which format to use to output the result. <spec>
                                  is either a name (or its shorthand) of some format
                                  understood by bombardier or a path to the
                                  user-defined template, which uses Go's
                                  text/template syntax, prefixed with 'path:' string
                                  (without single quotes), i.e.
                                  "path:/some/path/to/your.template" or
                                  "path:C:\some\path\to\your.template" in case of
                                  Windows. Formats understood by bombardier are:
      
                                    * plain-text (short: pt)
                                    * json (short: j)
    
    Args:
      <url>  Target's URL
    

    What actually happened?

    usage: bombardier [<flags>] <url>
    
    Fast cross-platform HTTP benchmarking tool
    
    Flags:
          --help                  Show context-sensitive help (also try --help-long
                                  and --help-man).
          --version               Show application version.
      -c, --connections=125       Maximum number of concurrent connections
      -t, --timeout=2s            Socket/request timeout
      -l, --latencies             Print latency statistics
      -m, --method=GET            Request method
      -b, --body=""               Request body
      -f, --body-file=""          File to use as request body
      -s, --stream                Specify whether to stream body using chunked
                                  transfer encoding or to serve it from memory
          --cert=""               Path to the client's TLS Certificate
          --key=""                Path to the client's TLS Certificate Private Key
      -k, --insecure              Controls whether a client verifies the server's
                                  certificate chain and host name
      -H, --header="K: V" ...     HTTP headers to use(can be repeated)
      -n, --requests=[pos. int.]  Number of requests
      -d, --duration=10s          Duration of test
      -r, --rate=[pos. int.]      Rate limit in requests per second
          --fasthttp              Use fasthttp client
          --http1                 Use net/http client with forced HTTP/1.x
          --http2                 Use net/http client with enabled HTTP/2.0
    
    Args:
      <url>  Target's URL
    
  • How can I send a basic post request with headers and a json body?

    How can I send a basic post request with headers and a json body?

    bombardier -c 1 -m POST -b "{\"refreshToken\": \"abc\"}" -H "Content-length: 23" -H "Content-Type : application/json; charset=utf-8" -H "X-JWT-Assertion : a very long JWT here" -n 1 http://myApi.com/MyOperation
    

    executing this I get a 400...

    if I copy/paste these values to postman, it works as expected...

  • Option to save response of the request

    Option to save response of the request

    Please provide an option to save response body

    What version of bombardier are you using?

    v1.2.5

    What operating system and processor architecture are you using (if relevant)?

    windows/amd64

    What you expected to happen?

    save response body of the request

    What actually happened?

    only gives http status code like 2xx, 4xx, etc.

  • bombardier version unspecified

    bombardier version unspecified

    Im installing bombardier in a Docker and bombardier --version outputs bombardier version unspecified linux/amd64

    #### install go && bombardier
    RUN wget https://go.dev/dl/go1.19.1.linux-amd64.tar.gz
    RUN rm -rf /usr/local/go && tar -C /usr/local -xzf go1.19.1.linux-amd64.tar.gz
    RUN echo 'export PATH=$PATH:/usr/local/go/bin:~/go/bin' >> ~/.bashrc
    RUN source ~/.bashrc
    RUN go install github.com/codesenberg/bombardier@latest
    RUN bombardier --version
    
  • body not allowed for GET

    body not allowed for GET

    This is an example of what a bug report can look like. Please, feel free to also provide any other information relevant to the issue.

    What version of bombardier are you using?

    % bombardier --version
    bombardier version unspecified linux/amd64
    

    I just installed now via go get -u github.com/codesenberg/bombardier ..so i guess thats 9376ab4 then?

    What operating system and processor architecture are you using (if relevant)?

    % uname -a
    Linux <snip> 5.13.19-2-MANJARO #1 SMP PREEMPT Sun Sep 19 21:31:53 UTC 2021 x86_64 GNU/Linux
    

    What did you do?

    I want to stress-test my elasticsearch server while running an index-update to see how many non-200 responses i get while closing/changing/opening-again the index. For that i want bombardier running a search (which is a GET-with-body request) while triggering an index-update in another shell.

    What you expected to happen?

    Allow me to send a payload with a GET request

    What actually happened?

     % bombardier -c125 -l  -H 'Content-type: application/json' -b '{"from": 0, "size": 10, "query": {"match_all": {}}}' 'http://elastic:elastic@elasticsearch:9200/watchlist_record/_search?pretty'
    GET and HEAD requests cannot have body
    

    Thats technically not correct, it always was ok the send a body with a GET request, it just shouldnt be used. But as mentioned here: https://stackoverflow.com/questions/978061/http-get-with-request-body that is also obsolete by now. curl for example allows to specify a body along with a GET request. If there is no special reason why this should not work with bombardier, i would love to see this also being allowed :) Shall we change

    - cantHaveBody = []string{"GET", "HEAD"}
    + cantHaveBody = []string{"HEAD"}
    

    ?

a benchmarking&stressing tool that can send raw HTTP requests

reqstress reqstress is a benchmarking&stressing tool that can send raw HTTP requests. It's written in Go and uses fasthttp library instead of Go's def

Dec 18, 2022
Plow is a high-performance HTTP benchmarking tool with real-time web UI and terminal displaying
Plow is a high-performance HTTP benchmarking tool with real-time web UI and terminal displaying

Plow is a HTTP(S) benchmarking tool, written in Golang. It uses excellent fasthttp instead of Go's default net/http due to its lightning fast performance.

Jan 9, 2023
Stress testing and benchmarking tool for the NEAR EVM

evm-bully --- stress testing and benchmarking tool for the NEAR EVM

May 30, 2022
📡 mock is a simple, cross-platform, cli app to simulate HTTP-based APIs.
 📡 mock is a simple, cross-platform, cli app to simulate HTTP-based APIs.

mock ?? mock is a simple, cross-platform, cli app to simulate HTTP-based APIs. About mock Mock allows you to spin up a local http server based of a .m

May 6, 2022
Benchmarking hash functions in Go

Experiment: Benchmarks of Hash Functions in Go This repository contains a small experiment of mine, trying out different hash functions and comparing

Jun 22, 2022
Benchmarking deferent Fibonacci functions and algorithms with running unit test

GoFibonacciBench Benchmarking deferent Fibonacci functions and algorithms with running unit test ... Introduction: Fibonacci numbers are special kinds

Feb 27, 2022
Check-load - Simple cross-platform load average check

Sensu load average check Table of Contents Overview Usage examples Configuration

Jun 16, 2022
Record and replay your HTTP interactions for fast, deterministic and accurate tests

go-vcr go-vcr simplifies testing by recording your HTTP interactions and replaying them in future runs in order to provide fast, deterministic and acc

Dec 25, 2022
Fast HTTP enumerator
Fast HTTP enumerator

monsoon A fast HTTP enumerator that allows you to execute a large number of HTTP requests, filter the responses and display them in real-time. Example

Jan 4, 2023
HTTP mock for Golang: record and replay HTTP/HTTPS interactions for offline testing

govcr A Word Of Warning I'm in the process of partly rewriting govcr to offer better support for cassette mutations. This is necessary because when I

Dec 28, 2022
Http test server written in Golang.

Dummy Server Http test server written in Golang. Can get any request method and log headers, body, path and remote address. Useful if you need to know

Oct 31, 2021
HTTP load testing tool and library. It's over 9000!
HTTP load testing tool and library. It's over 9000!

Vegeta Vegeta is a versatile HTTP load testing tool built out of a need to drill HTTP services with a constant request rate. It can be used both as a

Jan 7, 2023
Aquatone is a tool for visual inspection of websites across a large amount of hosts and is convenient for quickly gaining an overview of HTTP-based attack surface.

Aquatone is a tool for visual inspection of websites across a large amount of hosts and is convenient for quickly gaining an overview of HTTP-based attack surface.

Jan 6, 2023
Ditto is a CLI testing tool that helps you verify if multiple HTTP endpoints have the same outputs.

Ditto is a CLI testing tool that helps you verify if multiple HTTP endpoints have the same outputs.

Nov 24, 2021
A tool that integrates SQL, HTTP,interface,Redis mock

Mockit 目标:将mock变得简单,让代码维护变得容易 分支介绍 main 主分支,覆盖了单元测试 light 轻分支,去除了单元测试,简化了依赖项,方便其他团队使用 常见Mock难点 不同中间件,mock库设计模式不一致,学习代价高,差异化明显 mock方案强依赖服务端,无法灵活解耦 单元测试

Sep 22, 2022
Client tool for testing HTTP server timeouts

HTTP timeout test client While testing Go HTTP server timeouts I wrote this little tool to help me test. It allows for slowing down header write and b

Sep 21, 2022
Selenium Hub successor running browsers within containers. Scalable, immutable, self hosted Selenium-Grid on any platform with single binary.
Selenium Hub successor running browsers within containers. Scalable, immutable, self hosted Selenium-Grid on any platform with single binary.

Selenoid Selenoid is a powerful implementation of Selenium hub using Docker containers to launch browsers. Features One-command Installation Start bro

Jan 5, 2023
Cloud-Native A/B Testing Platform (WIP) 云原生的 A/B 测试平台

云原生的 A/B 测试系统 介绍 A/B 测试起源于农业工程。人们将土地划分为不同的地块,通过种植不同的农作物来确定在这些土地上更适合种植何种作物。随后 A/B 测试被广泛地应用于医学、工业等不同领域。

Sep 19, 2022
Create your own blazing fast mock server with just a JSON file!

Gmocker Run a blazing fast mock server in just seconds! ?? All you need is to make a json file that contains path and response mapping. See an example

Dec 21, 2022