{"id":13642475,"url":"https://github.com/envoyproxy/nighthawk","last_synced_at":"2025-04-05T02:12:32.453Z","repository":{"id":37580145,"uuid":"180498819","full_name":"envoyproxy/nighthawk","owner":"envoyproxy","description":"L7 (HTTP/HTTPS/HTTP2/HTTP3) performance characterization tool","archived":false,"fork":false,"pushed_at":"2024-04-08T14:17:43.000Z","size":42882,"stargazers_count":329,"open_issues_count":169,"forks_count":79,"subscribers_count":12,"default_branch":"main","last_synced_at":"2024-04-08T17:38:35.351Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/envoyproxy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"support/README.md","governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-04-10T03:59:28.000Z","updated_at":"2024-04-14T17:39:34.937Z","dependencies_parsed_at":"2023-10-13T07:19:41.707Z","dependency_job_id":"3a533b8d-3c70-40d0-bb8d-f957dd09ca45","html_url":"https://github.com/envoyproxy/nighthawk","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envoyproxy%2Fnighthawk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envoyproxy%2Fnighthawk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envoyproxy%2Fnighthawk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envoyproxy%2Fnighthawk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/envoyproxy","download_url":"https://codeload.github.com/envoyproxy/nighthawk/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247276189,"owners_count":20912288,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T01:01:31.871Z","updated_at":"2025-04-05T02:12:32.432Z","avatar_url":"https://github.com/envoyproxy.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"# Nighthawk\n\n*A L7 (HTTP/HTTPS/HTTP2) performance characterization tool*\n\n[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/envoyproxy/nighthawk/badge)](https://securityscorecards.dev/viewer/?uri=github.com/envoyproxy/nighthawk)\n\n## Current state\n\nNighthawk currently offers:\n\n- A load testing client which supports HTTP/1.1 and HTTP/2 over HTTP and HTTPS.\n(HTTPS certificates are not yet validated).\n- A simple [test server](source/server/README.md) which is capable of generating dynamic response sizes, as well as inject delays.\n- A binary to transform nighthawk output to well-known formats, allowing integration with other systems and dashboards.\n\n## Navigating the codebase\n\nSee [navigating the codebase](docs/root/navigating_the_codebase.md) for a\ndescription of the directory structure.\n\n## Building Nighthawk\n\n### Prerequisites\n\nNote that Nighthawk uses [Envoy's code](https://github.com/envoyproxy/envoy)\ndirectly, so building Envoy is a prerequisite for building Nighthawk. Start by\nlooking at [Envoy's\nbuilding](https://www.envoyproxy.io/docs/envoy/latest/start/building.html)\ndocumentation.\n\n#### Compiler requirements\n\nThe main supported way of building Nighthawk is with the Clang compiler. At\nleast Clang/LLVM 12+ is needed to successfully build Nighthawk.\n\n#### Bazel\n\nBoth Envoy and Nighthawk use the [Bazel](https://bazel.build/) build tool. The\nsteps required to set up Bazel are documented in Envoy's [Quick start Bazel\nbuild for\ndevelopers](https://github.com/envoyproxy/envoy/blob/main/bazel/README.md#quick-start-bazel-build-for-developers).\n\n### Building on Ubuntu\n\nThis section outlines the steps needed to build on Ubuntu. Note that these steps\ninclude commands that are documented in the prerequisites section above.\n\n#### Install required packages\n\nRun the following command to install the required packages.\n```\nsudo apt-get install \\\n   autoconf \\\n   automake \\\n   cmake \\\n   curl \\\n   libtool \\\n   make \\\n   ninja-build \\\n   patch \\\n   python3-pip \\\n   unzip \\\n   virtualenv\n```\n\n#### Install Clang/LLVM\n\nNote that depending on the chosen Ubuntu version, you may need to manually\ninstall a never version of Clang/LLVM. The installed version of Clang can be\nverified by running:\n```\nclang -v\n```\n\nIf you do need to install a newer version, be sure to use Ubuntu's\n`update-alternatives` or a similar approach to switch to using the newer\nClang/LLVM. See [issue#832](https://github.com/envoyproxy/nighthawk/issues/832)\nfor one possible approach.\n\nRun the following commands to install Clang/LLVM.\n```\nsudo apt install -y lld clang llvm lld lldb\nsudo apt install -y clang-{format,tidy,tools} clang-doc clang-examples\n```\n\n#### Install Bazelisk instead of bazel\n\n[Bazelisk](https://github.com/bazelbuild/bazelisk) is recommended, since it\nautomatically chooses and downloads the appropriate Bazel version. If you\nalready have Bazel installed, it is strongly recommended to remove it.\n\nRun the following to remove bazel.\n```\nsudo apt-get remove bazel\n```\n\nRun the following to install Bazelisk.\n```\nsudo wget -O /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-$([ $(uname -m) = \"aarch64\" ] \u0026\u0026 echo \"arm64\" || echo \"amd64\")\nsudo chmod +x /usr/local/bin/bazel\n```\n\n#### Clone Nighthawk and setup Clang as the compiler\n\nRun the following to clone the Nighthawk repository and instruct Bazel to use\nClang.\n```\ngit clone https://github.com/envoyproxy/nighthawk\ncd nighthawk/\necho \"build --config=clang\" \u003e\u003e user.bazelrc\n```\n\n#### Install Python libraries\n\nIt is advisable to use the same version of Python as the one listed at the top of `tools/base/requirements.txt`. While other versions may also work, the chances of success are greatest if using the same one.\n\nRecommended: Use `virtualenv` to avoid conflicts between Nighthawk's Python package version requirements and other versions already on your system:\n```\npython3 -m venv ~/my_nh_venv\nsource ~/my_nh_venv/bin/activate\n```\n\nNote: Avoid creating the environment under the Nighthawk project directory.\n\nInstall Python packages required for Nighthawk (whether using `virtualenv` or not):\n```\npip3 install --user -r tools/base/requirements.txt\n```\n\nIf `pip3 install` fails, you will need to troubleshoot the Python environment before attempting to build and test Nighthawk.\n\n#### Build and testing  Nighthawk\n\nYou can now use the CI script to build Nighthawk.\n```\nci/do_ci.sh build\n```\n\nOr to execute its tests.\n```\nci/do_ci.sh test\n```\n\nNote that after building completes, the Nighthawk binaries are located in the\n`bazel-bin/` directory located at the root of the cloned Nighthawk repository.\n\n## Using the Nighthawk client CLI\n\nFor using the Nighthawk test server, see [here](source/server/README.md).\n\n```bash\n➜ bazel-bin/nighthawk_client --help\n```\n\n\u003c!-- BEGIN USAGE --\u003e\n```\n\nUSAGE:\n\nbazel-bin/nighthawk_client  [--user-defined-plugin-config \u003cstring\u003e] ...\n[--latency-response-header-name \u003cstring\u003e]\n[--stats-flush-interval-duration \u003cduration\u003e]\n[--stats-flush-interval \u003cuint32_t\u003e]\n[--stats-sinks \u003cstring\u003e] ... [--no-duration]\n[--simple-warmup]\n[--request-source-plugin-config \u003cstring\u003e]\n[--request-source \u003curi format\u003e] [--label\n\u003cstring\u003e] ... [--multi-target-use-https]\n[--multi-target-path \u003cstring\u003e]\n[--multi-target-endpoint \u003cstring\u003e] ...\n[--experimental-h2-use-multiple-connections]\n[--nighthawk-service \u003curi format\u003e]\n[--jitter-uniform \u003cduration\u003e] [--open-loop]\n[--experimental-h1-connection-reuse-strategy\n\u003cmru|lru\u003e] [--no-default-failure-predicates]\n[--failure-predicate \u003cstring:uint64_t\u003e] ...\n[--termination-predicate \u003cstring:uint64_t\u003e]\n... [--trace \u003curi format\u003e]\n[--sequencer-idle-strategy \u003cspin|poll\n|sleep\u003e] [--max-concurrent-streams\n\u003cuint32_t\u003e] [--max-requests-per-connection\n\u003cuint32_t\u003e] [--max-active-requests\n\u003cuint32_t\u003e] [--max-pending-requests\n\u003cuint32_t\u003e] [--transport-socket \u003cstring\u003e]\n[--upstream-bind-config \u003cstring\u003e]\n[--tls-context \u003cstring\u003e]\n[--request-body-size \u003cuint32_t\u003e]\n[--request-header \u003cstring\u003e] ...\n[--request-method \u003cGET|HEAD|POST|PUT|DELETE\n|CONNECT|OPTIONS|TRACE\u003e] [--address-family\n\u003cauto|v4|v6\u003e] [--burst-size \u003cuint32_t\u003e]\n[--prefetch-connections] [--output-format\n\u003cjson|human|yaml|dotted|fortio\n|experimental_fortio_pedantic|csv\u003e] [-v\n\u003ctrace|debug|info|warn|error|critical\u003e]\n[--concurrency \u003cstring\u003e]\n[--http3-protocol-options \u003cstring\u003e] [-p\n\u003chttp1|http2|http3\u003e] [--h2] [--timeout\n\u003cuint32_t\u003e] [--duration \u003cuint32_t\u003e]\n[--connections \u003cuint32_t\u003e] [--rps\n\u003cuint32_t\u003e] [--] [--version] [-h] \u003curi\nformat\u003e\n\n\nWhere:\n\n--user-defined-plugin-config \u003cstring\u003e  (accepted multiple times)\nWIP - will throw unimplemented error. Optional configurations for\nplugins that collect data about responses received by NH and attach a\ncorresponding UserDefinedOutput to the Result. Example (json):\n{name:\"nighthawk.fake_user_defined_output\"\n,typed_config:{\"@type\":\"type.googleapis.com/nighthawk.FakeUserDefinedO\nutputConfig\",fail_data:\"false\"}}\n\n--latency-response-header-name \u003cstring\u003e\nSet an optional header name that will be returned in responses, whose\nvalues will be tracked in a latency histogram if set. Can be used in\ntandem with the test server's response option\n\"emit_previous_request_delta_in_response_header\" to record elapsed\ntime between request arrivals. Default: \"\"\n\n--stats-flush-interval-duration \u003cduration\u003e\nTime interval (in Duration) between flushes to configured stats sinks.\nFor example '1s' or '1.000000001s'. Mutually exclusive with\n--stats-flush-interval.\n\n--stats-flush-interval \u003cuint32_t\u003e\nTime interval (in seconds) between flushes to configured stats sinks.\nMutually exclusive with --stats-flush-interval-duration. Default: 5.\n\n--stats-sinks \u003cstring\u003e  (accepted multiple times)\nStats sinks (in json) where Nighthawk metrics will be flushed. This\nargument is intended to be specified multiple times. Example (json):\n{name:\"envoy.stat_sinks.statsd\"\n,typed_config:{\"@type\":\"type.googleapis.com/envoy.config.metrics.v3.St\natsdSink\",tcp_cluster_name:\"statsd\"}}\n\n--no-duration\nRequest infinite execution. Note that the default failure predicates\nwill still be added. Mutually exclusive with --duration.\n\n--simple-warmup\nPerform a simple single warmup request (per worker) before starting\nexecution. Note that this will be reflected in the counters that\nNighthawk writes to the output. Default is false.\n\n--request-source-plugin-config \u003cstring\u003e\n[Request\nSource](https://github.com/envoyproxy/nighthawk/blob/main/docs/root/ov\nerview.md#requestsource) plugin configuration in json. Mutually\nexclusive with --request-source. Example (json):\n{name:\"nighthawk.stub-request-source-plugin\"\n,typed_config:{\"@type\":\"type.googleapis.com/nighthawk.request_source.S\ntubPluginConfig\",test_value:\"3\"}}\n\n--request-source \u003curi format\u003e\nRemote gRPC source that will deliver to-be-replayed traffic. Each\nworker will separately connect to this source. For example\ngrpc://127.0.0.1:8443/. Mutually exclusive with\n--request_source_plugin_config.\n\n--label \u003cstring\u003e  (accepted multiple times)\nLabel. Allows specifying multiple labels which will be persisted in\nstructured output formats.\n\n--multi-target-use-https\nUse HTTPS to connect to the target endpoints. Otherwise HTTP is used.\nMutually exclusive with providing a URI.\n\n--multi-target-path \u003cstring\u003e\nThe single absolute path Nighthawk should request from each target\nendpoint. Required when using --multi-target-endpoint. Mutually\nexclusive with providing a URI.\n\n--multi-target-endpoint \u003cstring\u003e  (accepted multiple times)\nTarget endpoint in the form IPv4:port, [IPv6]:port, or DNS:port. This\nargument is intended to be specified multiple times. Nighthawk will\nspread traffic across all endpoints with round robin distribution.\nMutually exclusive with providing a URI.\n\n--experimental-h2-use-multiple-connections\nDO NOT USE: This option is deprecated, if this behavior is desired,\nset --max-concurrent-streams to one instead.\n\n--nighthawk-service \u003curi format\u003e\nNighthawk service uri. Example: grpc://localhost:8843/. Default is\nempty.\n\n--jitter-uniform \u003cduration\u003e\nAdd uniformly distributed absolute request-release timing jitter. For\nexample, to add 10 us of jitter, specify .00001s. Default is empty /\nno uniform jitter.\n\n--open-loop\nEnable open loop mode. When enabled, the benchmark client will not\nprovide backpressure when resource limits are hit.\n\n--experimental-h1-connection-reuse-strategy \u003cmru|lru\u003e\nChoose picking the most recently used, or least-recently-used\nconnections for re-use.(default: mru). WARNING: this option is\nexperimental and may be removed or changed in the future!\n\n--no-default-failure-predicates\nDisables the default failure predicates, indicating that Nighthawk\nshould continue sending load after observing error status codes and\nconnection errors.\n\n--failure-predicate \u003cstring:uint64_t\u003e  (accepted multiple times)\nFailure predicate. Allows specifying a counter name plus threshold\nvalue for failing execution. Defaults to not tolerating error status\ncodes and connection errors. Example: benchmark.http_5xx:4294967295.\n\n--termination-predicate \u003cstring:uint64_t\u003e  (accepted multiple times)\nTermination predicate. Allows specifying a counter name plus threshold\nvalue for terminating execution.\n\n--trace \u003curi format\u003e\nTrace uri. Example: zipkin://localhost:9411/api/v2/spans. Default is\nempty.\n\n--sequencer-idle-strategy \u003cspin|poll|sleep\u003e\nChoose between using a busy spin/yield loop or have the thread poll or\nsleep while waiting for the next scheduled request (default: spin).\n\n--max-concurrent-streams \u003cuint32_t\u003e\nMax concurrent streams allowed on one HTTP/2 or HTTP/3 connection.\nDoes not apply to HTTP/1. (default: 2147483647).\n\n--max-requests-per-connection \u003cuint32_t\u003e\nMax requests per connection (default: 4294937295).\n\n--max-active-requests \u003cuint32_t\u003e\nThe maximum allowed number of concurrently active requests. HTTP/2\nonly. (default: 100).\n\n--max-pending-requests \u003cuint32_t\u003e\nMax pending requests (default: 0, no client side queuing. Specifying\nany other value will allow client-side queuing of requests).\n\n--transport-socket \u003cstring\u003e\nTransport socket configuration in json. Mutually exclusive with\n--tls-context. Example (json): {name:\"envoy.transport_sockets.tls\"\n,typed_config:{\"@type\":\"type.googleapis.com/envoy.extensions.transport\n_sockets.tls.v3.UpstreamTlsContext\"\n,common_tls_context:{tls_params:{cipher_suites:[\"-ALL:ECDHE-RSA-AES128\n-SHA\"]}}}}\n\n--upstream-bind-config \u003cstring\u003e\nBindConfig in json. If specified, this configuration is used to bind\nnewly established upstream connections. Allows selecting the source\naddress, port and socket options used when sending requests. Example\n(json): {source_address:{address:\"127.0.0.1\",port_value:0}}\n\n--tls-context \u003cstring\u003e\nDEPRECATED, use --transport-socket instead. TlS context configuration\nin json. Mutually exclusive with --transport-socket. Example (json):\n{common_tls_context:{tls_params:{cipher_suites:[\"-ALL:ECDHE-RSA-AES128\n-SHA\"]}}}\n\n--request-body-size \u003cuint32_t\u003e\nSize of the request body to send. NH will send a number of consecutive\n'a' characters equal to the number specified here. (default: 0, no\ndata).\n\n--request-header \u003cstring\u003e  (accepted multiple times)\nRaw request headers in the format of 'name: value' pairs. This\nargument may specified multiple times.\n\n--request-method \u003cGET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE\u003e\nRequest method used when sending requests. The default is 'GET'.\n\n--address-family \u003cauto|v4|v6\u003e\nNetwork address family preference. Possible values: [auto, v4, v6].\nThe default output format is 'AUTO'.\n\n--burst-size \u003cuint32_t\u003e\nRelease requests in bursts of the specified size (default: 0).\n\n--prefetch-connections\nUse proactive connection prefetching (HTTP/1 only).\n\n--output-format \u003cjson|human|yaml|dotted|fortio\n|experimental_fortio_pedantic|csv\u003e\nOutput format. Possible values: [\"json\", \"human\", \"yaml\", \"dotted\",\n\"fortio\", \"experimental_fortio_pedantic\", \"csv\"]. The default output\nformat is 'human'.\n\n-v \u003ctrace|debug|info|warn|error|critical\u003e,  --verbosity \u003ctrace|debug\n|info|warn|error|critical\u003e\nVerbosity of the output. Possible values: [trace, debug, info, warn,\nerror, critical]. The default level is 'info'.\n\n--concurrency \u003cstring\u003e\nThe number of concurrent event loops that should be used. Specify\n'auto' to let Nighthawk leverage all vCPUs that have affinity to the\nNighthawk process. Note that increasing this results in an effective\nload multiplier combined with the configured --rps and --connections\nvalues. Default: 1.\n\n--http3-protocol-options \u003cstring\u003e\nHTTP3 protocol options (envoy::config::core::v3::Http3ProtocolOptions)\nin json. If specified, Nighthawk uses these HTTP3 protocol options\nwhen sending requests. Only valid with --protocol http3. Mutually\nexclusive with any other command line option that would modify the\nhttp3 protocol options, e.g. --max-concurrent-streams. Example (json):\n{quic_protocol_options:{max_concurrent_streams:1}}\n\n-p \u003chttp1|http2|http3\u003e,  --protocol \u003chttp1|http2|http3\u003e\nThe protocol to encapsulate requests in. Possible values: [http1,\nhttp2, http3]. The default protocol is 'http1' when neither of --h2 or\n--protocol is used. Mutually exclusive with --h2.\n\n--h2\nDEPRECATED, use --protocol instead. Encapsulate requests in HTTP/2.\nMutually exclusive with --protocol. Requests are encapsulated in\nHTTP/1 by default when neither of --h2 or --protocol is used.\n\n--timeout \u003cuint32_t\u003e\nConnection connect timeout period in seconds. Default: 30.\n\n--duration \u003cuint32_t\u003e\nThe number of seconds that the test should run. Default: 5. Mutually\nexclusive with --no-duration.\n\n--connections \u003cuint32_t\u003e\nThe maximum allowed number of concurrent connections per event loop.\nHTTP/1 only. Default: 100.\n\n--rps \u003cuint32_t\u003e\nThe target requests-per-second rate. Default: 5.\n\n--,  --ignore_rest\nIgnores the rest of the labeled arguments following this flag.\n\n--version\nDisplays version information and exits.\n\n-h,  --help\nDisplays usage information and exits.\n\n\u003curi format\u003e\nURI to benchmark. http:// and https:// are supported, but in case of\nhttps no certificates are validated. Provide a URI when you need to\nbenchmark a single endpoint. For multiple endpoints, set\n--multi-target-* instead.\n\n\nL7 (HTTP/HTTPS/HTTP2) performance characterization tool.\n\n```\n\u003c!-- END USAGE --\u003e\n\n### Nighthawk gRPC service\n\nThe gRPC service can be used to start a server which is able to perform back-to-back benchmark runs upon request. The service interface definition [can be found here.](https://github.com/envoyproxy/nighthawk/blob/59a37568783272a6438b5697277d4e56aa16ebbe/api/client/service.proto)\n\n\n```bash\n➜ bazel-bin/nighthawk_service --help\n```\n\n\u003c!-- BEGIN USAGE --\u003e\n```\n\nUSAGE:\n\nbazel-bin/nighthawk_service  [--service \u003ctraffic-generator-service\n|dummy-request-source\u003e]\n[--listener-address-file \u003c\u003e] [--listen\n\u003caddress:port\u003e] [--] [--version] [-h]\n\n\nWhere:\n\n--service \u003ctraffic-generator-service|dummy-request-source\u003e\nSpecifies which service to run. Default 'traffic-generator-service'.\n\n--listener-address-file \u003c\u003e\nLocation where the service will write the final address:port on which\nthe Nighthawk grpc service listens. Default empty.\n\n--listen \u003caddress:port\u003e\nThe address:port on which the Nighthawk gRPC service should listen.\nDefault: 0.0.0.0:8443.\n\n--,  --ignore_rest\nIgnores the rest of the labeled arguments following this flag.\n\n--version\nDisplays version information and exits.\n\n-h,  --help\nDisplays usage information and exits.\n\n\nL7 (HTTP/HTTPS/HTTP2) performance characterization tool.\n\n```\n\u003c!-- END USAGE --\u003e\n\n### Nighthawk output transformation utility\n\nNighthawk comes with a tool to transform its json output to its other supported output formats.\n\n\n```bash\n➜ bazel-bin/nighthawk_output_transform --help\n```\n\n\u003c!-- BEGIN USAGE --\u003e\n```\n\nUSAGE:\n\nbazel-bin/nighthawk_output_transform  --output-format \u003cjson|human|yaml\n|dotted|fortio\n|experimental_fortio_pedantic|csv\u003e\n[--] [--version] [-h]\n\n\nWhere:\n\n--output-format \u003cjson|human|yaml|dotted|fortio\n|experimental_fortio_pedantic|csv\u003e\n(required)  Output format. Possible values: [\"json\", \"human\", \"yaml\",\n\"dotted\", \"fortio\", \"experimental_fortio_pedantic\", \"csv\"].\n\n--,  --ignore_rest\nIgnores the rest of the labeled arguments following this flag.\n\n--version\nDisplays version information and exits.\n\n-h,  --help\nDisplays usage information and exits.\n\n\nL7 (HTTP/HTTPS/HTTP2) performance characterization transformation tool.\n\n```\n\u003c!-- END USAGE --\u003e\n\n**Example:** transform json output to fortio compatible format\n\n\u003e Notice that the default output format for `nighthawk_client` is \"human\", therefore to produce a json output you must run `nighthawk_client` with `--output-format json`. This json output is the one that can be transformed to the different formats as shown in the example below.\n\n```\n➜ /your/json/output/file.json | bazel-bin/nighthawk_output_transform --output-format fortio\n```\n\n## A sample benchmark run\n\n```bash\n# start the benchmark target (Envoy with a single worker in this case) on cpu-core 3.\n➜ taskset -c 3 envoy --concurrency 1 --config-path ~/envoy.yaml\n\n# run a quick benchmark using cpu-cores 4 and 5.\n➜ taskset -c 4-5 bazel-bin/nighthawk_client --rps 1000 --connections 4 --concurrency auto --prefetch-connections -v info http://127.0.0.1:10000/\n[21:28:12.690578][27849][I] [source/client/client.cc:71] Detected 2 (v)CPUs with affinity..\n[21:28:12.690621][27849][I] [source/client/client.cc:75] Starting 2 threads / event loops. Test duration: 5 seconds.\n[21:28:12.690627][27849][I] [source/client/client.cc:77] Global targets: 8 connections and 2000 calls per second.\n[21:28:12.690632][27849][I] [source/client/client.cc:81]    (Per-worker targets: 4 connections and 1000 calls per second)\nNighthawk - A layer 7 protocol benchmarking tool.\n\nQueueing and connection setup latency\n  samples: 9992\n  mean:    0s 000ms 002us\n  pstdev:  0s 000ms 000us\n\n  Percentile  Count       Latency\n  0           1           0s 000ms 001us\n  0.5         5013        0s 000ms 002us\n  0.75        7496        0s 000ms 002us\n  0.8         8008        0s 000ms 002us\n  0.9         8996        0s 000ms 002us\n  0.95        9493        0s 000ms 002us\n  0.990625    9899        0s 000ms 003us\n  0.999023    9983        0s 000ms 004us\n  1           9992        0s 000ms 027us\n\nRequest start to response end\n  samples: 9992\n  mean:    0s 000ms 108us\n  pstdev:  0s 000ms 061us\n\n  Percentile  Count       Latency\n  0           1           0s 000ms 073us\n  0.5         4997        0s 000ms 111us\n  0.75        7495        0s 000ms 113us\n  0.8         7997        0s 000ms 114us\n  0.9         8993        0s 000ms 116us\n  0.95        9493        0s 000ms 120us\n  0.990625    9899        0s 000ms 130us\n  0.999023    9983        0s 000ms 528us\n  1           9992        0s 004ms 083us\n\nInitiation to completion\n  samples: 9992\n  mean:    0s 000ms 113us\n  pstdev:  0s 000ms 061us\n\n  Percentile  Count       Latency\n  0           1           0s 000ms 077us\n  0.5         4996        0s 000ms 115us\n  0.75        7495        0s 000ms 118us\n  0.8         7998        0s 000ms 118us\n  0.9         8993        0s 000ms 121us\n  0.95        9493        0s 000ms 124us\n  0.990625    9899        0s 000ms 135us\n  0.999023    9983        0s 000ms 588us\n  1           9992        0s 004ms 090us\n\nCounter                                 Value       Per second\nclient.benchmark.http_2xx               9994        1998.80\nclient.upstream_cx_http1_total          8           1.60\nclient.upstream_cx_overflow             2           0.40\nclient.upstream_cx_rx_bytes_total       36008382    7201676.40\nclient.upstream_cx_total                8           1.60\nclient.upstream_cx_tx_bytes_total       599640      119928.00\nclient.upstream_rq_pending_total        2           0.40\nclient.upstream_rq_total                9994        1998.80\n\n[21:28:18.522403][27849][I] [source/client/client.cc:279] Done.\n```\n\n## Visualizing the output of a benchmark\n\nNighthawk supports transforming the output into other well-known formats, such as:\n\n- `dotted`: Provides integration with Prometheus\n- `fortio`: Provides integration with [Fortio's report-only UI](https://github.com/fortio/fortio#report-only-ui)\n\nThe following is an example of a nighthawk benchmark visualized via the Fortio UI.\n\n```bash\nfortio report --data-dir ./samples/fortio_data\n```\n\n![Fortio Large Report](./samples/fortio_reports/large.png)\n\n## Accuracy and repeatability considerations when using the Nighthawk client\n\n- Processes not related to the benchmarking task at hand may add significant noise. Consider stopping any\n  processes that are not needed.\n- Be aware that power state management and CPU Frequency changes are able to introduce significant noise.\n  When idle, Nighthawk uses a busy loop to achieve precise timings when starting requests, which helps minimize this.\n  Still, consider disabling C-state changes in the system BIOS.\n- Be aware that CPU thermal throttling may skew results.\n- Consider using `taskset` to isolate client and server. On machines with multiple physical CPUs there is a choice here.\n  You can partition client and server on the same physical processor, or run each of them on a different physical CPU. Be aware of the latency effects of interconnects such as QPI.\n- Consider disabling hyper-threading.\n- Consider tuning the benchmarking system for low (network) latency. You can do that manually, or install [tuned](http://manpages.ubuntu.com/manpages/bionic/man8/tuned-adm.8.html) and run:\n\n| As this may change boot flags, take precautions, and familiarize yourself with the tool on systems that you don't mind breaking. For example, running this has been observed to mess up dual-boot systems! |\n| --- |\n\n```bash\nsudo tuned-adm profile network-latency\n```\n\n- When using Nighthawk with concurrency \u003e 1 or multiple connections, workers may produce significantly different results. That can happen because of various reasons:\n  - Server fairness. For example, connections may end up being serviced by the same server thread, or not.\n  - One of the clients may be unlucky and structurally spend time waiting on requests from the other(s)\n    being serviced due to interference of request release timings and server processing time.\n- Consider using separate machines for the clients and server(s).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fenvoyproxy%2Fnighthawk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fenvoyproxy%2Fnighthawk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fenvoyproxy%2Fnighthawk/lists"}