A more modern http framework benchmarker supporting HTTP/1 and HTTP/2 benchmarks.

Overview

rewrk

A more modern http framework benchmark utility.

F:\rewrk> rewrk -h http://127.0.0.1:5000 -t 12 -c 60 -d 5s

Benchmarking 60 connections @ http://127.0.0.1:5000 for 5 seconds
  Latencies:
    Avg      Stdev    Min      Max    
    3.27ms   0.40ms   1.95ms   9.39ms
  Requests:
    Total:  91281  Req/Sec: 18227.81
  Transfer:
    Total: 1.13 MB Transfer Rate: 231.41 KB/Sec

With optional --pct flag

+ --------------- + --------------- +
|   Percentile    |   Avg Latency   |
+ --------------- + --------------- +
|      99.9%      |     6.88ms      |
|       99%       |     5.62ms      |
|       95%       |     4.62ms      |
|       90%       |     4.24ms      |
|       75%       |     3.78ms      |
|       50%       |     3.49ms      |
+ --------------- + --------------- +

Motivation

The motivation behind this project extends from developers tunnel visioning on benchmarks like techempower that use the benchmarking tool called wrk.

The issue is that wrk only handle some of the HTTP spec and is entirely biased towards frameworks and servers that can make heavy use of HTTP/1 Pipelining which is no longer enabled in most modern browsers or clients, this can give a very unfare and unreasonable set of stats when comparing frameworks as those at the top are simply better at using a process which is now not used greatly.

This is where rewrk comes in, this benchmarker is built on top of hyper's client api and brings with it many advantages and more realistic methods of benchmarking.

Current features

  • Supports both HTTP/1 and HTTP/2.
  • Pipelining is disabled giving a more realistic idea on actual perfromance.
  • Multi-Platform support, developed on Windows but will run on Mac and Linux aswell.

To do list

  • Add a random artificial delay benchmark to simulate random latency with clients.
  • Arithmetic benchmark to simulate diffrent loads across clients.
  • State checking, making the frameworks and servers use all of their api rather than a minimised set.
  • JSON deserialization and validation benchmarks and checking.
  • Truly concurrent HTTP/2 benchmark.

Usage

Usage is relatively simple, if you have a compiled binary simply run using the CLI.

Example

Here's an example to produce the following benchmark:

  • 256 connections (-c 256)
  • HTTP/2 only (--http2)
  • 12 threads (-t 12)
  • 15 seconds (-d 15s)
  • with percentile table (--pct)
  • on host http://127.0.0.1:5000 (-h http://127.0.0.1:5000)

CLI command:
rewrk -c 256 -t 12 -d 15s -h http://127.0.0.1:5000 --http2 --pct

CLI Help

To bring up the help menu simply run rewrk --help to produce this:

USAGE:
    rewrk.exe [FLAGS] [OPTIONS] --duration  --host 

FLAGS:
        --help       Prints help information
        --http2      Set the client to use http2 only. (default is http/1) e.g. '--http2'
        --pct        Displays the percentile table after benchmarking.
    -V, --version    Prints version information

OPTIONS:
    -c, --connections     Set the amount of concurrent e.g. '-c 512' [default: 1]
    -d, --duration           Set the duration of the benchmark.
    -h, --host                   Set the host to bench e.g. '-h http://127.0.0.1:5050'
    -t, --threads             Set the amount of threads to use e.g. '-t 12' [default: 1]

Building from source

Building from source is incredibly simple, just make sure you have a stable version of Rust installed before you start.

With Cargo Run

    • Clone the repo source code
    • Run cargo run --release --

With Cargo Build

    • Clone the repo source code
    • Run cargo build --release
    • Extract the binary from the release folder
    • Binary ready to use.
Comments
  • Support setting request method, headers, and body

    Support setting request method, headers, and body

    I've been benchmarking axum's JSON handling today using rewrk with great success! But I'm having issues testing JSON input since you cannot set method, headers, and body, so figured I'd try and add it.

    Example usage:

    rewrk -d 10s -h http://localhost:3000 -m post -H "content-type: application/json" -b "{\"msg\":\"foobar\"}"
    

    Just let me know if you want me to split things up into separate PRs.

    opened by davidpdrsn 4
  • Freshly coded new client

    Freshly coded new client

    • Reordered dependencies and removed their patch version.
    • Much more readable and less complex client code.
    • Better implemented timeouts.
    • Better error messages.
    • Use anyhow on client code.
    • Error logging.
    • Uses tokio-native-tls instead of tokio-rustls.
    opened by programatik29 3
  • Data Transfer only reads body size

    Data Transfer only reads body size

    This can be a potentially big issue for people and likely miss-leading as the current system does not support messuring the headers aswell, not sure what a possible soloution is if hyper doesnt give a direct interface for this.

    opened by ChillFish8 3
  • rewrk fails to process arguments when used via some external program

    rewrk fails to process arguments when used via some external program

    Hi, I am currently building a framework benchmark tool using rust, and just switched from using wrk to rewrk. Loving it so far as it doesn't has inconsistencies like wrk.

    There are some issues with clap when it comes to parsing through another program, for example rust's own std::process::Command utility. I am also submitting a PR to get rid all these issues.

    Problem

    Here's a demo code that my benchmark program is using (using absolute path just to debug it further)

    code

    The exact same arguments seem to work okay with wrk, and any other programs. However, because of this clap issue, rewrk expects us to either specify arguments using t=2 threads=2 or t2.

    Solution

    Threads

    // It's trying to parse a `usize` when the value is like ` 3` - with a space, which fails
    // clap doesn't removes that space
    let threads: usize = match args.value_of("threads").unwrap_or("1").parse()
    

    connections

    // Same issue as above
    let conns: usize = match args.value_of("connections").unwrap_or("1").parse()
    

    rounds

    // Same issue as above
    let rounds: usize = args  .value_of("rounds") .unwrap_or("1").parse()
    

    host/url

    // again the `uri` fails to parse since it has a space ` http://localhost:3000`
    let user_input = UserInput::new(bench_type, uri_string).await?;
    

    There's a quick fix - trimming values and that will do it for all the use cases. I'll be submitting a PR that fixes all these.

    opened by ishtms 1
  • prevent division by zero panics

    prevent division by zero panics

    When 0 requests are processed successfully, various functions would panic when trying to calculate request averages. This avoids calling those functions by bailing early.

    opened by robjtede 1
  • [ Display Instability ] high connections silencing logs.

    [ Display Instability ] high connections silencing logs.

    It seems that at higher concurrent connections (possibly when the comouter running the bench cannot produce that many) cause the tool to silence any results.

    Reproduced at 1024 connections on my 2c 2t latop

    opened by ChillFish8 1
  • Fixes #25 - Adds a one-line installation command

    Fixes #25 - Adds a one-line installation command

    Command will download, compile, and install using cargo install

    Note: I copied the convention of using markdown bulleted lists inside markdown numbered lists

    Fixes #25

    opened by finnbear 0
  • Installation guide / `cargo install` integration

    Installation guide / `cargo install` integration

    Based on the README file, it seems like the only way to install this tool is by cloning the repository, building from source, and then figuring out a symbolic link to put the binary in $PATH. This is not unlike my experience with wrk itself, but it leaves an easier option to be desired.

    Specifically, it would be nice if there was a one-line, cargo install based command to download, compile, and install rewrk to some bin directory in $PATH.

    ~~Publishing on https://crates.io is likely a prerequisite.~~

    opened by finnbear 0
  • program will return error if anything fails

    program will return error if anything fails

    Errors should be ignored by default until error logging is implemented and there should be a command line argument to return early if an error happens.

    opened by programatik29 0
  • Some crazy error rate when testing ASP.NET Core API endpoints

    Some crazy error rate when testing ASP.NET Core API endpoints

    When benchmarking ASP.NET API endpoints, rewrk is yielding some bizarre numbers (unexpected low) and almost all requests got error responses. On the other hand, testing Rust API endpoints (Actix, Axum) and Node.js endpoints (Nest, Fastify) seems fine. Any thoughts? Thanks~

    I am running Fedora 36.

    ASP.NET Core (.net 6 + Minimal API) result:

    > rewrk -c 256 -t 12 -d 15s -h http://127.0.0.1:5000      
    Beginning round 1...
    Benchmarking 256 connections @ http://127.0.0.1:5000 for 15 second(s)
      Latencies:
        Avg      Stdev    Min      Max      
        4.96ms   1.82ms   0.12ms   29.61ms  
      Requests:
        Total: 772075  Req/Sec: 51517.15
      Transfer:
        Total: 88.36 MB Transfer Rate: 5.90 MB/Sec
    
    772112 Errors: connection closed
    
    > wrk -c 256 -t 12 -d 15s http://127.0.0.1:5000           
    Running 15s test @ http://127.0.0.1:5000
      12 threads and 256 connections
      Thread Stats   Avg      Stdev     Max   +/- Stdev
        Latency   360.27us    0.90ms  43.45ms   96.32%
        Req/Sec    78.35k    11.33k  184.48k    76.26%
      14071720 requests in 15.10s, 1.60GB read
    Requests/sec: 932057.72
    Transfer/sec:    108.44MB
    

    NestJS (w/ Fastify):

    > rewrk -c 256 -t 12 -d 15s -h http://127.0.0.1:3000                 
    Beginning round 1...
    Benchmarking 256 connections @ http://127.0.0.1:3000 for 15 second(s)
      Latencies:
        Avg      Stdev    Min      Max      
        2.18ms   0.56ms   1.02ms   39.25ms  
      Requests:
        Total: 1756945 Req/Sec: 117196.97
      Transfer:
        Total: 296.57 MB Transfer Rate: 19.78 MB/Sec
    
    > wrk -c 256 -t 12 -d 15s http://127.0.0.1:3000     
    Running 15s test @ http://127.0.0.1:3000
      12 threads and 256 connections
      Thread Stats   Avg      Stdev     Max   +/- Stdev
        Latency     2.17ms  202.46us  15.30ms   96.03%
        Req/Sec     9.75k     1.13k   39.03k    99.11%
      1748814 requests in 15.09s, 295.20MB read
    Requests/sec: 115855.62
    Transfer/sec:     19.56MB
    
    
    opened by HymanZHAN 7
  • ReWrk 0.5

    ReWrk 0.5

    This merges the v2 changes to ReWrk.

    As part of v2, the ReWrk project and part of the lnx-cli tool are being merged to make it easier to maintain as well as make the tooling more adaptable and generic giving it a wider range of benchmarking use cases.

    This PR is very much still a WIP but plans to add the following:

    • Benchmarking warm-up
    • Body upload
    • Sample data export: CSV, JSON, etc...
    • Scriptable setup process ran before each round of benchmarking. Provided by Rhai.
    • Benchmarking as a library: ReWrk will become an importable crate and a CLI tool allowing people to extend ReWrk and the benchmarking logic into other tooling.
    opened by ChillFish8 5
  • Support metrics to be exposed for monitoring system like prometheus

    Support metrics to be exposed for monitoring system like prometheus

    Should we have app server running to expose the metrics which can be consumed by Prometheus. Also I am thinking of publishing a histogram as a report which can give further metrics details in more granular fashion

    opened by himanshumps 1
  • Replace native-tls with reactls

    Replace native-tls with reactls

    I think we will have issues while building musl due to openssl dependency on native-tls.

    Please let me know and I can work on replacing it.

    I do agree that we will lose support for older cipher suites.

    opened by himanshumps 2
Releases(0.3.2)
Owner
Harrison Burt
17yr/o Programmer in Python, Rust, Js and Go lang.
Harrison Burt
ratpack: a simpleton's HTTP framework (for rust-lang)

ratpack: a simpleton's HTTP framework (for rust-lang) ratpack is idealized in the simplicity of the sinatra (ruby) framework in its goal, and attempts

ZeroTier, Inc. 5 Jun 29, 2022
An easy and powerful Rust HTTP Client

reqwest An ergonomic, batteries-included HTTP Client for Rust. Plain bodies, JSON, urlencoded, multipart Customizable redirect policy HTTP Proxies HTT

Sean McArthur 6.8k Dec 31, 2022
Minimal Rust HTTP client for both native and WASM

ehttp: a minimal Rust HTTP client for both native and WASM If you want to do HTTP requests and are targetting both native and web (WASM), then this is

Emil Ernerfeldt 105 Dec 25, 2022
xh is a friendly and fast tool for sending HTTP requests. It reimplements as much as possible of HTTPie's excellent design, with a focus on improved performance.

xh is a friendly and fast tool for sending HTTP requests. It reimplements as much as possible of HTTPie's excellent design, with a focus on improved performance

Mohamed Daahir 3.4k Jan 6, 2023
An HTTP library for Rust

hyper A fast and correct HTTP implementation for Rust. HTTP/1 and HTTP/2 Asynchronous design Leading in performance Tested and correct Extensive produ

null 11k Jan 8, 2023
FeignHttp is a declarative HTTP client. Based on rust macros.

FeignHttp is a declarative HTTP client. Based on rust macros. Features Easy to use Asynchronous request Configurable timeout settings Suppor

null 46 Nov 30, 2022
Pretend is a macros-based declarative Rust HTTP client

pretend is a modular, Feign-inspired HTTP, client based on macros. It's goal is to decouple the definition of a REST API from it's implementation.

null 24 Aug 3, 2022
🐱‍👤 Drop-in HTTP replacement module for Garry's Mod

??‍?? gmsv_reqwest This module is a drop-in replacement for Garry's Mod's HTTP function, inspired by gmsv_chttp created by timschumi. The module uses

William 38 Dec 12, 2022
Multi-stream HTTP downloader using range requests

chooch - An Amazing Project Downloads files faster than wget/curl (in theory) using multiple connections. Chooch recycles the slowest connection and r

null 13 Sep 14, 2022
Pyre - A fast python HTTP server inspired by japronto written in rust.

Pyre - A fast python HTTP server inspired by japronto written in rust.

null 135 Nov 26, 2022
HTTPie: human-friendly CLI HTTP client for the API era

HTTPie: human-friendly CLI HTTP client for the API era HTTPie (pronounced aitch-tee-tee-pie) is a command-line HTTP client. Its goal is to make CLI in

null 25.4k Dec 30, 2022
A backend providing a HTTP REST like interface for uploading files written in rust.

UploadServer A backend providing a HTTP REST like interface for uploading files written in rust. API Documentation License This project is licensed un

null 4 Nov 20, 2022
rh: user-friendly command-line HTTP client

Rust HTTP Cli The command name in your terminal is rh. rh: user-friendly command-line HTTP client rh is a user-friendly, lightweight and performant co

null 8 Nov 30, 2022
Typed, correct GraphQL requests and responses in Rust

graphql_client A typed GraphQL client library for Rust. Features Precise types for query variables and responses. Supports GraphQL fragments, objects,

GraphQL Rust 914 Dec 27, 2022
🕵️Scrape multiple media providers on a cron job and dispatch webhooks when changes are detected.

Jiu is a multi-threaded media scraper capable of juggling thousands of endpoints from different providers with unique restrictions/requirements.

Xetera 47 Dec 6, 2022
A crate to convert bytes to something more useable and the other way around in a way Compatible with the Confluent Schema Registry. Supporting Avro, Protobuf, Json schema, and both async and blocking.

#schema_registry_converter This library provides a way of using the Confluent Schema Registry in a way that is compliant with the Java client. The rel

Gerard Klijs 69 Dec 13, 2022
Hitbox is an asynchronous caching framework supporting multiple backends and suitable for distributed and for single-machine applications.

Hitbox is an asynchronous caching framework supporting multiple backends and suitable for distributed and for single-machine applications.

null 62 Dec 27, 2022
PRQL is a modern language for transforming data — a simpler and more powerful SQL

PRQL Pipelined Relational Query Language, pronounced "Prequel". PRQL is a modern language for transforming data — a simpler and more powerful SQL. Lik

PRQL 6.5k Jan 5, 2023
A recreation of the famous Cobol with a more modern approach.

Cobalt Lang Discord Warning To compile and use Cobalt on windows you will need to follow this StackOverflow post Ye, im just as confused as you... Who

Shadow Wizurd Money Gang Leader 4 Feb 15, 2023
The Computer Language Benchmarks Game: Rust implementations

The Computer Language Benchmarks Game: Rust implementations This is the version I propose to the The Computer Language Benchmarks Game. For regex-dna,

Guillaume P. 69 Jul 11, 2022