Fast cross-platform HTTP benchmarking tool written in Go

Overview

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
Issues
  • 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.

    awaiting-feedback 
    opened by greenpau 18
  • 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

    opened by n0madic 12
  • 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]

    question 
    opened by PhanSon95 9
  • 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.

    bug 
    opened by orthoxerox 9
  • 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!

    question 
    opened by her 9
  • 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.

    question 
    opened by devguysin 6
  • 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

    opened by pmcgrath 5
  • 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.

    opened by nielsole 4
  • 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
    
    question 
    opened by likezjuisee 4
  • 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 [email protected]' instead.
            For more information, see https://golang.org/doc/go-get-install-deprecation
            or run 'go help get' or 'go help install'.
    
    opened by r0fls 3
  • 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
    
    opened by mikalaisyty 3
  • 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:[email protected]: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"}
    

    ?

    opened by leberknecht 0
  • Can the stress test using different parameters within on testflow

    Can the stress test using different parameters within on testflow

    What version of bombardier are you using?

    bombardier version v1.2.5 linux/amd64

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

    linux/amd64 ubuntu

    What you expected to happen?

    eg: for GET method, target api is https://ip:port/some-route/some-method?id= can i put a collection of id in some place(like somefile), and the request use random id in my id-collection

    for POST method, can i put a collection of body in somefile, and the request use randomly or for loop

    opened by murrays1208049 1
  • 'http2: no cached connection was available' when receiving goAway frame during load test

    'http2: no cached connection was available' when receiving goAway frame during load test

    What version of bombardier are you using?

    ./bombardier --version
    bombardier version v1.2.5 darwin/amd64
    

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

    darwin/amd64

    What did you do?

    I use bombardier to make some load tests of a remote service and verify that the service meets the performance expectations. The service is exposed in http2 (can fallback to http1 thanks to alpn) and the bombardier load test is run as follow:

    ./bombardier -c 20 -d 30s --http2 -k -l -m GET https://my-remote-http2-service.com

    Everything is working well until I try to check the behavior of my service during a rolling update (check that there is no loss, errors , latency or throughput degradation).

    During a rolling update, each pod is deleted 1 by 1 and active connection is gracefully shutdown by sending a goAway frame. All pending requests are honored. Everything is made to keep the service reachable during the rolling update.

    The result of the bombardier command shows the following error:

    Statistics        Avg      Stdev        Max
      Reqs/sec    375273.79  118131.95  565257.94
      Latency       46.94us   429.41us   247.28ms
      Latency Distribution
         50%    10.00us
         75%    28.00us
         90%   109.00us
         95%   199.00us
         99%   486.00us
      HTTP codes:
        1xx - 0, 2xx - 2241, 3xx - 0, 4xx - 0, 5xx - 0
        others - 11255262
      Errors:
        Get "https://my-remote-http2-service.com": http2: no cached connection was available - 11255262
    

    What you expected to happen?

    I was expecting bombardier to be able to create a new connection like it is able to do with http1.1 when it receives a Connection: close header (the same process with --http1 option works like a charm without any error).

    What actually happened?

    The goAway frame seems received and well interpreted but bombardier keeps trying to reuse the connection which seems to lead to the http2: no cached connection was available error.

    Thanks for you help.

    opened by jhaeyaert 0
  • Can the stress test of random parameters be realized?

    Can the stress test of random parameters be realized?

    What version of bombardier are you using?

    bombardier --version v1.2.5
    

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

    linux/amd64

    What did you do?

    I hope that the function of random parameters can be realized, but unfortunately no relevant information can be found

    opened by zhenlei520 0
Releases(v1.2.5)
Owner
Максим Федосеев
Максим Федосеев
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

Utku Sen 153 May 30, 2022
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.

ddc 3k Jun 26, 2022
Stress testing and benchmarking tool for the NEAR EVM

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

Project Aurora 28 May 30, 2022
📡 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

Bruno Schaatsbergen 8 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

Roman Atachiants 6 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

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

Sensu load average check Table of Contents Overview Usage examples Configuration

KOHMURA Jin 0 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

Marin Atanasov Nikolov 888 Jul 3, 2022
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

RedTeam Pentesting GmbH 338 Jun 28, 2022
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

Seb C 105 May 18, 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

Yury Krylov 0 Oct 31, 2021
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

Tomás Senart 19.8k Jun 27, 2022
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.

Michael Henriksen 4.7k Jun 26, 2022
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.

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

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

SHIHUO 14 Apr 19, 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

Adam Pritchard 7 May 11, 2022
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

Aerokube 2.2k Jun 23, 2022
Cloud-Native A/B Testing Platform (WIP) 云原生的 A/B 测试平台

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

Dongyue Studio 31 Mar 3, 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

Ananto 49 Apr 13, 2022