h2load - Man Page

HTTP/2 benchmarking tool

Synopsis

h2load [Options]... [URI]...

Description

benchmarking tool for HTTP/2 server

<URI>

Specify URI to access.   Multiple URIs can be specified. URIs are used  in this order for each  client.  All URIs are used, then  first URI is used and then  2nd URI, and so  on.  The  scheme, host  and port  in the  subsequent URIs, if present,  are ignored.  Those in  the first URI are used solely.  Definition of a base URI overrides all scheme, host or port values.

Options

-n,  --requests=<N>

Number of  requests across all  clients.  If it  is used with --timing-script-file option,  this option specifies the number of requests  each client performs rather than the number of requests  across all clients.  This option is ignored if timing-based  benchmarking is enabled (see --duration option).

Default: 1

-c,  --clients=<N>

Number  of concurrent  clients.   With  -r option,  this specifies the maximum number of connections to be made.

Default: 1

-t,  --threads=<N>

Number of native threads.

Default: 1

-i,  --input-file=<PATH>

Path of a file with multiple URIs are separated by EOLs. This option will disable URIs getting from command-line. If '-' is given as <PATH>, URIs will be read from stdin. URIs are used  in this order for each  client.  All URIs are used, then  first URI is used and then  2nd URI, and so  on.  The  scheme, host  and port  in the  subsequent URIs, if present,  are ignored.  Those in  the first URI are used solely.  Definition of a base URI overrides all scheme, host or port values.

-m,  --max-concurrent-streams=<N>

Max  concurrent  streams  to issue  per  session.   When http/1.1  is used,  this  specifies the  number of  HTTP pipelining requests in-flight.

Default: 1

-f,  --max-frame-size=<SIZE>

Maximum frame size that the local endpoint is willing to receive.

Default: 16K

-w,  --window-bits=<N>

Sets the stream level initial window size to (2**<N>)-1. For  QUIC, <N>  is  capped to  26  (roughly 64MiB).   It defaults  to  24 (16MiB)  for  QUIC,  and 30  for  other protocols.

-W,  --connection-window-bits=<N>

Sets  the  connection  level   initial  window  size  to (2**<N>)-1.

Default: 30

-H,  --header=<HEADER>

Add/Override a header to the requests.

--ciphers=<SUITE>

Set  allowed cipher  list  for TLSv1.2  or earlier.   The format of the string is described in OpenSSL ciphers(1).

Default: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384

--tls13-ciphers=<SUITE>

Set allowed cipher list for  TLSv1.3.  The format of the string is described in OpenSSL ciphers(1).

Default: TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256

-p,  --no-tls-proto=<PROTOID>

Specify ALPN identifier of the  protocol to be used when accessing http URI without SSL/TLS. Available protocols: h2c and http/1.1

Default: h2c

-d,  --data=<PATH>

Post FILE to  server.  The request method  is changed to POST.   For  http/1.1 connection,  if  -d  is used,  the maximum number of in-flight pipelined requests is set to 1.

-r,  --rate=<N>

Specifies  the  fixed  rate  at  which  connections  are created.   The   rate  must   be  a   positive  integer, representing the  number of  connections to be  made per rate period.   The maximum  number of connections  to be made  is  given  in  -c   option.   This  rate  will  be distributed among  threads as  evenly as  possible.  For example,  with   -t2  and   -r4,  each  thread   gets  2 connections per period.  When the rate is 0, the program will run  as it  normally does, creating  connections at whatever variable rate it  wants.  The default value for this option is 0.  -r and -D are mutually exclusive.

--rate-period=<DURATION>

Specifies the time  period between creating connections. The period  must be a positive  number, representing the length of the period in time.  This option is ignored if the rate option is not used.  The default value for this option is 1s.

-D,  --duration=<DURATION>

Specifies the main duration for the measurements in case of timing-based  benchmarking.  -D  and -r  are mutually exclusive.

--warm-up-time=<DURATION>

Specifies the  time  period  before  starting the actual measurements, in  case  of  timing-based benchmarking. Needs to provided along with -D option.

-T,  --connection-active-timeout=<DURATION>

Specifies  the maximum  time that  h2load is  willing to keep a  connection open,  regardless of the  activity on said connection.  <DURATION> must be a positive integer, specifying the amount of time  to wait.  When no timeout value is  set (either  active or inactive),  h2load will keep  a  connection  open indefinitely,  waiting  for  a response.

-N,  --connection-inactivity-timeout=<DURATION>

Specifies the amount  of time that h2load  is willing to wait to see activity  on a given connection.  <DURATION> must  be a  positive integer,  specifying the  amount of time  to wait.   When no  timeout value  is set  (either active or inactive), h2load  will keep a connection open indefinitely, waiting for a response.

--timing-script-file=<PATH>

Path of a file containing one or more lines separated by EOLs.  Each script line is composed of two tab-separated fields.  The first field represents the time offset from the start of execution, expressed as a positive value of milliseconds  with microsecond  resolution.  The  second field represents the URI.  This option will disable URIs getting from  command-line.  If '-' is  given as <PATH>, script lines will be read  from stdin.  Script lines are used in order for each client.   If -n is given, it must be less  than or  equal to the  number of  script lines, larger values are clamped to the number of script lines. If -n is not given,  the number of requests will default to the  number of  script lines.   The scheme,  host and port defined in  the first URI are  used solely.  Values contained  in  other  URIs,  if  present,  are  ignored. Definition of a  base URI overrides all  scheme, host or port   values.   --timing-script-file   and  --rps   are mutually exclusive.

-B,  --base-uri=(<URI>|unix:<PATH>)

Specify URI from which the scheme, host and port will be used  for  all requests.   The  base  URI overrides  all values  defined either  at  the command  line or  inside input files.  If argument  starts with "unix:", then the rest  of the  argument will  be treated  as UNIX  domain socket path.   The connection is made  through that path instead of TCP.   In this case, scheme  is inferred from the first  URI appeared  in the  command line  or inside input files as usual.

--alpn-list=<LIST>

Comma delimited list of  ALPN protocol identifier sorted in the  order of preference.  That  means most desirable protocol comes  first.  The parameter must  be delimited by a single comma only  and any white spaces are treated as a part of protocol string.

Default: h2,http/1.1

--h1

Short        hand        for        --alpn-list=http/1.1 --no-tls-proto=http/1.1,    which   effectively    force http/1.1 for both http and https URI.

--h3

Short hand for  --alpn-list=h3, which effectively forces HTTP/3.

--header-table-size=<SIZE>

Specify decoder header table size.

Default: 4K

--encoder-header-table-size=<SIZE>

Specify encoder header table size.  The decoder (server) specifies  the maximum  dynamic table  size it  accepts. Then the negotiated dynamic table size is the minimum of this option value and the value which server specified.

Default: 4K

--log-file=<PATH>

Write per-request information to a file as tab-separated columns: start  time as  microseconds since  epoch; HTTP status code;  microseconds until end of  response.  More columns may be added later.  Rows are ordered by end-of- response  time when  using  one worker  thread, but  may appear slightly  out of order with  multiple threads due to buffering.  Status code is -1 for failed streams.

--qlog-file-base=<PATH>

Enable qlog output and specify base file name for qlogs. Qlog is emitted  for each connection.  For  a given base name   "base",    each   output   file    name   becomes "base.M.N.sqlog" where M is worker ID and N is client ID (e.g. "base.0.3.sqlog").  Only effective in QUIC runs.

--connect-to=<HOST>[:<PORT>]

Host and port to connect  instead of using the authority in <URI>.

--rps=<N>

Specify request  per second for each  client.  --rps and --timing-script-file are mutually exclusive.

--groups=<GROUPS>

Specify the supported groups.

Default: X25519:P-256:P-384:P-521

--no-udp-gso

Disable UDP GSO.

--max-udp-payload-size=<SIZE>

Specify the maximum outgoing UDP datagram payload size.

--ktls

Enable ktls.

--sni=<DNSNAME>

Send  <DNSNAME> in  TLS  SNI, overriding  the host  name specified in URI.

--histogram

Plot histogram for performance statistics.

--tls-session-file=<PATH>

Read  TLS session  from <PATH>,  and set  it to  all TLS connections to  perform the  session resumption.   It is also used  to store  the new TLS  session.  At  most one session is written to the given file.

--output-file=<PATH>

Write the measurement results  to <PATH> in JSON format. This  basically includes  all  numbers  reported to  the normal   output.     In   addition,    for   performance measurements, all raw samples are included.

-v,  --verbose

Output debug information.

--version

Display version information and exit.

-h,  --help

Display this help and exit.

The <SIZE> argument is an integer and an optional unit (e.g., 10K is 10 * 1024).  Units are K, M and G (powers of 1024).

The <DURATION> argument is an integer and an optional unit (e.g., 1s is 1 second and 500ms is 500 milliseconds).  Units are h, m, s or ms (hours, minutes, seconds and milliseconds, respectively).  If a unit is omitted, a second is used as unit.

Output

Request Metrics

requests
total

The total number of requests h2load was instructed to make.

started

The number of requests initiated by the tool.

done

The number of requests that reached completion.

succeeded

Requests resulting in an HTTP 2xx or 3xx status code.

failed

The total number of failed requests.  This includes both errored requests and requests that completed with a non-2xx/3xx status code.

errored

A subset of failed where the requests failed due to network-level issues (e.g., TCP resets, RST_STREAM) rather than HTTP status codes.

timeout

A subset of errored where the connection timed out before completion.

status codes

The specific count of received HTTP status codes categorized by class (2xx, 3xx, 4xx, 5xx).

Traffic Metrics

traffic
total

Total application data bytes received "on the wire" (decrypted if using TLS).

headers

Total bytes used for response headers (pre-decompression).

space savings

Header compression efficiency, calculated as:

(1 - headers / decompressed_headers) * 100

where headers is the compressed size and decompressed_headers is the size after decompression.

data

Total bytes received in response bodies.

Performance Statistics

Metric Definitions
request

The duration from sending the first byte of a request to receiving the last byte of the response.

connect

The time taken to establish a connection, including TLS handshakes.

TTFB

The duration until the first byte of application data is received from the server (decrypted if using TLS).

req/s

The requests per second measured individually across all clients.

min RTT

The minimum RTT (QUIC).

smoothed RTT

The smoothed RTT (QUIC).

packets sent

The number of packets sent (QUIC).

packets recv

The number of packets received (QUIC).

packets lost

The number of packets declared lost (QUIC).

GRO packets

The number of packets received in a single recvmsg call (QUIC).

Distribution Fields
min / max

The absolute minimum and maximum values recorded.

median

The 50th percentile value.

p95 / p99

The 95th and 99th percentiles, indicating tail performance.

mean

The arithmetic average of all samples.

sd

The standard deviation (measure of data dispersion).

+/- sd

The percentage of successful samples falling within one standard deviation of the mean (mean +/- sd).

Flow Control

h2load sets large flow control window by default, and effectively disables flow control to avoid under utilization of server performance.  To set smaller flow control window, use -w and -W options.  For example, use -w16 -W16 to set default window size described in HTTP/2 protocol specification.

See Also

nghttp(1), nghttpd(1), nghttpx(1)

Author

Tatsuhiro Tsujikawa

Referenced By

nghttp(1), nghttpd(1), nghttpx(1).

Apr 19, 2026 1.69.0 nghttp2