Options Reference

The ghz command line has numerous command line options. You can run ghz --help to view all available options.

-config

Path to the JSON or TOML config file that specifies all the test settings.

Config file settings can be combined with command line arguments. CLI options overwrite config file options.

  1. ghz --config=./config.json -c 20 -n 1000

--proto

The path to The Protocol Buffer .proto file for input. If no -proto or -protoset options are used, we attempt to perform server reflection.

--protoset

Alternatively we use compiled protoset file (containing compiled descriptors, produced by protoc) as input. To create a protoset file, invoke protoc with the *.proto files that define the service. For example:

  1. protoc --proto_path=. --descriptor_set_out=bundle.protoset *.proto

If no -proto or -protoset options are used, we attempt to perform server reflection.

--call

A fully-qualified method name in ‘package.Service/Method’ or ‘package.Service.Method’ format. For example: helloworld.Greeter.SayHello. With regard to measurement, we use WithStatsHandler option to capture call metrics. Specifically we only capture the End event which contains stats when an RPC ends. This should include the download of the payload and deserializing of the data.

-i, --import-paths

Comma separated list of proto import paths. The current working directory and the directory of the protocol buffer file specified using -proto are automatically added to the import list.

--cacert

Path to the file containing trusted root certificates for verifying the server. By default ghz tries to create a secure connection using the system’s default root certificate. The certificate file can be specified using -cacert option. The TLS verification can be skipped using -skipTLS option.

--cert

Path to the file containing client certificate (public key), to present to the server. Must also provide -key option when this is used.

--key

File containing client private key, to present to the server. Must also provide -cert option.

--cname

Server name override when validating TLS certificate.

--skipTLS

Skip TLS client verification of the server’s certificate chain and host name.

--insecure

Use plaintext and insecure connection.

--authority

Value to be used as the :authority pseudo-header. Only works if -insecure is used.

--async

Make requests asynchronous as soon as possible. Does not wait for request to finish before sending next one.

-r, --rps

Rate limit in how many requsts per second (RPS) we perform in total. Default is no rate limit. The total RPS will be distributed among all the workers as specified by concurrency options.

--load-schedule

Specifies the load schedule. Options are const, step, or line. Default is const.
With const load schedule we attempt to perform a constant RPS load as specified with the q option.
With step load schedule we do a step increase or decrease of RPS load as dictated by step load options: load-start, load-step, load-end, load-step-duration, and load-max-duration. With line load schedule we do a linear increase or decrease of RPS load as dictated by step load options: load-start, load-step, load-end, and load-max-duration. Linear load is essentially step load with slop being specified using load-step option and load-step-duration is 1s.

Examples:

  1. -n 10000 -c 10 --load-schedule=step --load-start=50 --load-step=10 --load-step-duration=5s

Performs step load starting at 50 RPS and inscreasing by 10 RPS every 5s until we reach 10000 total requests. The RPS load is distributed among the 10 workers, all sharing 1 connection.

  1. -n 10000 -c 10 --load-schedule=step --load-start=50 --load-end=150 --load-step=10 --load-step-duration=5s

Performs step load starting at 50 RPS and inscreasing by 10 RPS every 5s until we reach 150 RPS at which point the load is sustained at constant RPS rate until we reach 10000 total requests. The RPS load is distributed among the 10 workers, all sharing 1 connection.

  1. -n 10000 -c 10 --load-schedule=step --load-start=50 --load-step=10 --load-step-duration=5s --load-max-duration=60s

Performs step load starting at 50 RPS and inscreasing by 10 RPS every 5s until 60s has elapsed at which point the load is sustained at that RPS rate until we reach 10000 total requests. The RPS load is distributed among the 10 workers, all sharing 1 connection.

  1. -n 10000 -c 10 --load-schedule=line --load-start=200 --load-step=-2 --load-end=50

Performs linear load starting at 200 RPS and decreasing by 2 RPS every 1s until 20 RPS has been reached, at which point the load is sustained at that RPS rate until we reach 10000 total requests. The RPS load is distributed among the 10 workers, all sharing 1 connection.

--load-start

Specifies the starting RPS load value for step or line load schedules.

--load-step

Specifies the load step value or slope value for step or line schedules.

--load-end

Optional, specifies the load end value for step or line load schedules. Load adjustment is performed until either load-end rate is reached or load-max-duration duration has elapsed, which ever comes first.

--load-max-duration

Optional, maximum duration to apply load adjustment. After this time has elapsed, constant load is performed at load-end setting value. Load adjustment is performed until either load-end rate is reached or load-max-duration duration has elapsed, which ever comes first.

-c, --concurrency

Number of workers to run concurrently when using const concurrency scheduler.

--concurrency-schedule

Controls the concurrency (number of workers) adjustment, similarly how load settings control the RPS load adjustment. Options are const, step, or line. Default is const.

Examples:

  1. -n 100000 --rps 200 --concurrency-schedule=step --concurrency-start=5 --concurrency-step=5 --concurrency-end=50 --concurrency-step-duration=5s

Performs RPS load of 200 RPS. The number of concurrent workers starts at 5 and is increased by 5 every 5s until we reach 50 workers. At that point we keep the sustained 200 RPS load spread over the 50 workers until total of 10000 requests is reached. That means as we increase the number of total concurrent workers, their share of RPS load decreases.

  1. -n 20000 -rps 200 --concurrency-schedule=step --concurrency-start=10 --concurrency-step=10 --concurrency-step-duration=5s --concurrency-max-duration=60s

Performs RPS load of 200 RPS. The number of concurrent workers starts at 10 and is increased by 10 every 5s until 60s has elapsed. At that point we keep the sustained 200 RPS load spread over the same number of workers until total of 20000 requests is reached.

  1. -n 10000 --rps 200 --concurrency-schedule=line --concurrency-start=200 --concurrency-step=-2 --concurrency-end=20

Performs RPS load of 200 RPS. The number of concurrent workers starts at 200 and is decreased linearly by 2 every 1s until we are at 20 concurrent workers. At that point we keep the sustained 200 RPS load spread over the same number of workers until total of 10000 requests is reached. As total number of active concurrent workers decreases, their share of RPS load increases.

--concurrency-start

Concurrency start value for step and line concurrency schedules.

--concurrency-end

Concurrency end value for step and line concurrency schedules.

--concurrency-step=1

Concurrency step / slope value for step and line concurrency schedules.

--concurrency-step-duration

Specifies the concurrency step duration value for step concurrency schedule.

--concurrency-max-duration

Specifies the max concurrency adjustment duration value for step or line concurrency schedule.

-n, --total

The total number of requests to run. Default is 200. The combination of -c and -n are critical in how the benchmarking is done. ghz takes the -c argument and spawns that many worker goroutines. In parallel these goroutines each do their share (n / c) requests. So for example with the default -c 50 -n 200 options we would spawn 50 goroutines which in parallel each do 4 requests.

-t, --timeout

Timeout for each request. Default is 20s, use zero value for infinite.

-z, --duration

Duration of application to send requests. When duration is reached, application stops and exits. If duration is specified, n is ignored. Examples: -z 10s or -z 3m.

-x, --max-duration

Maximum duration of application to send requests with n setting respected. If duration is reached before n requests are completed, application stops and exits. Examples: -x 10s or -x 3m.

--duration-stop

Option on how to handle in-flight requests when duration specified using duration option is reached. Options are close, wait, and ignore. close will cause the connections to close immediately, and any requests that have yet to complete will likely error out and be reported with transport is closing error. wait will make all in-flight requests to be completed and reported. These requests still have the regular request timeout constraint. Finally, ignore option is similar to close that the connections are terminated immediately, however any in-flight requests that complete are completely ignored in the reporting.

-d, --data

The call data as stringified JSON. If the value is @ then the request contents are read from standard input (stdin). Example: -d '{"name":"Bob"}'.

For unary requests we accept a single message or an array of messages. In case of a single message we repeat the unary call with this message throughout the test. In case of array the messages will be sent in round-robin fashion. For example with -d '[{"name":"Joe"},{"name":"Kate"},{"name":"Sara"}]' the server will get Joe, Kate and Sara requests repeatedly.

For client streaming or bi-directional calls we accept a JSON array of messages, each element representing a single message within the stream call. For example: -d '[{"name":"Joe"},{"name":"Kate"},{"name":"Sara"}]' can be used as input for a client streaming or bidi call. In case of streaming calls if a single object is given for data then it is automatically converted to an array with single element. For example -d '{"name":"Joe"}' is equivalent to -d '[{"name":"Joe"}]. Round-robin for streaming requests is not supported.

In case of client streaming we send all the messages in the input array and then we close and receive.

-D, --data-file

The path for call data JSON file. For example, -D /home/user/file.json or -D ./file.json.

-b, --binary

The call data comes as serialized protocol buffer messages read from standard input.

We support two formats of binary data: single message and multiple count-delimited messages. See writing a message on how to serialize a single message.

For multiple messages prefix each message with its length in bytes. See streaming multiple messages in protobuf documentation.

Code example:

  1. msg1 := &helloworld.HelloRequest{}
  2. msg1.Name = "Alice"
  3. msg2 := &helloworld.HelloRequest{}
  4. msg2.Name = "Bob"
  5. buf := proto.Buffer{}
  6. _ = buf.EncodeMessage(msg1)
  7. _ = buf.EncodeMessage(msg2)
  8. binData := buf.Bytes() // pass this as input

-B, --binary-file

Path for the call data as serialized binary message. The format is the same as for -b switch.

-m, --metadata

Request metadata as stringified JSON.

-M, --metadata-file

Path for call metadata JSON file. For example, -M /home/user/metadata.json or -M ./metadata.json.

--stream-interval

Stream interval duration. Spread stream sends by given amount. Only applies to client and bidi streaming calls. Example: 100ms.

--stream-call-duration

Maximum stream call duration. For client streaming and bidi calls, we’ll send messages until this duration expires.

For server streaming calls we will receive message until the duration has expired. Note that in server streaming calls the cancellation will result in call cancelled error.

Example: 500ms.

--stream-call-count

The maximum number of message sends or receives the client will perform in a streaming call before closing the stream and ending the call. For client and bidi streaming calls this dictates the number of messages we will send.

If the data array contains more elements than the count, only data up to the number specified will be used.

If the data array contains fewer elements than the count specified, all the data will be iterated over repeatedly until count limit is reached.

For server streaming calls we will receive message until the specified count is reached. Note that in server streaming calls the cancellation will result in call cancelled error.

Examples:

  1. --stream-call-count=2 -d '[{"name":"Joe"},{"name":"Kate"},{"name":"Sara"}]'

Will cause only [{"name":"Joe"},{"name":"Kate"}] to be sent. Similarly:

  1. --stream-call-count=5 -d '[{"name":"Joe"},{"name":"Kate"},{"name":"Sara"}]'

Will cause [{"name":"Joe"},{"name":"Kate"},{"name":"Sara"},{"name":"Joe"},{"name":"Kate"}] to be sent.

--stream-dynamic-messages

In streaming calls, regenerate and apply call template data on every message send operation. This is helpful in combination with template functionality to generate data for every message sent in a streaming call. For example:

  1. --stream-dynamic-messages=true --stream-call-count=5 -d '{"name":"{{randomString 8 }}"}'

Will result in streaming call with the following data sent:

  1. [{"name":"sKNdMCIb"},{"name":"KLVXDvn1"},{"name":"RJ3knnBh"},{"name":"FTBqQ7nl"},{"name":"FzeMQIWo"}]

Contrast that with the default dynamic messages setting turned off; which means the template data will be applied only once for each stream call request, but not for each message sent in the streaming call.

  1. --stream-call-count=5 -d '{"name":"{{randomString 8 }}"}'

Results in the following data sent:

  1. [{"name":"5hL64dd0"},{"name":"5hL64dd0"},{"name":"5hL64dd0"},{"name":"5hL64dd0"},{"name":"5hL64dd0"}]

--reflect-metadata

Reflect metadata as stringified JSON used only for reflection request.

--max-recv-message-size

Maximum message size the client can receive. Can be specified as bytes, or using human readable value such as 42 MB.

--max-send-message-size

Maximum message size the client can send. Can be specified as bytes, or using human readable value such as 42 MB.

-o, --output

Output path. If none is provided by default we print to standard output (stdout).

-O, --format

Output type. If none provided, a summary is printed.

  • "csv" - outputs the response metrics in comma-separated values format.
  • "json" - outputs the metrics report in JSON format.
  • "pretty" - outputs the metrics report in pretty JSON format.
  • "html" - outputs the metrics report as HTML.
  • "influx-summary" - outputs the metrics summary as InfluxDB line protocol.
  • "influx-details" - outputs the metrics details as InfluxDB line protocol.
  • "prometheus" - outputs the metrics summary in Prometheus exposition format.

See output formats page for details.

--skipFirst

Skip the first n responses from the report. Helps remove initial warm-up requests from skewing the results.

--connections

By default we use a single gRPC connection for the whole test run, and the concurrency (-c) is achieved using goroutine workers sharing this single connection. The number of gRPC connections used can be controlled using this parameter. This parameter cannot exceed concurrency option. The specified number of connections will be distributed evenly to be shared among the concurrency goroutine workers. So for example a concurrency of 10 and using 5 connections will result in 10 goroutine workers, each pair of 2 workers sharing 1 of the 5 connections. Each worker will get its share of the total number of requests specified using -n option.

--connect-timeout

Connection timeout duration for the initial connection dial. Default is 10s.

--keepalive

Keepalive time duration. Only used if present and above 0.

--name

A user specified name for the test.

--tags

JSON string representation of user-defined string tags. This is mainly for reporting purposes. For example -tags '{"env":"staging","created by":"Joe Developer"}'.

--cpus

Number of used cpu cores to be used for the test. The default is the total number of logical CPUs on the local machine.

--debug

Enables debug logging to a file specified by the path. The debug logger outputs JSON line format. Use this only for debugging purposes.

  1. ghz --insecure \
  2. --proto ./protos/greeter.proto \
  3. --call helloworld.Greeter.SayHello \
  4. -d '{"name":"Joe"}' -c 5 -n 50 -m '{"request-id":"{{.RequestNumber}}", "timestamp":"{{.TimestampUnix}}"}' \
  5. --debug ./logs/debug.json \
  6. 0.0.0.0:50051

-e, --enable-compression

Enable gzip compression on requests.

--count-errors

By default stats for fastest, slowest, average, histogram, and latency distributions only take into account the responses with OK status. This option enabled counting of erroneous (non-OK) responses in stats calculations as well.

-v, --version

Print the version.

-h, --help

Show context-sensitive help (also try —help-long and —help-man).