- Options Reference
-config
--proto
--protoset
--call
-i
,--import-paths
--cacert
--cert
--key
--cname
--skipTLS
--insecure
--authority
--async
-r
,--rps
--load-schedule
--load-start
--load-step
--load-end
--load-max-duration
-c
,--concurrency
--concurrency-schedule
--concurrency-start
--concurrency-end
--concurrency-step=1
--concurrency-step-duration
--concurrency-max-duration
-n
,--total
-t
,--timeout
-z
,--duration
-x
,--max-duration
--duration-stop
-d
,--data
-D
,--data-file
-b
,--binary
-B
,--binary-file
-m
,--metadata
-M
,--metadata-file
--stream-interval
--stream-call-duration
--stream-call-count
--stream-dynamic-messages
--reflect-metadata
--max-recv-message-size
--max-send-message-size
-o
,--output
-O
,--format
--skipFirst
--connections
--connect-timeout
--keepalive
--name
--tags
--cpus
--debug
-e
,--enable-compression
--count-errors
-v
,--version
-h
,--help
Options Reference
The ghz
command line has numerous command line options. You can run ghz --help
to view all available options.
-config
--proto
--protoset
--call
-i
,--import-paths
--cacert
--cert
--key
--cname
--skipTLS
--insecure
--authority
--async
-r
,--rps
--load-schedule
--load-start
--load-step
--load-end
--load-max-duration
-c
,--concurrency
--concurrency-schedule
--concurrency-start
--concurrency-end
--concurrency-step=1
--concurrency-step-duration
--concurrency-max-duration
-n
,--total
-t
,--timeout
-z
,--duration
-x
,--max-duration
--duration-stop
-d
,--data
-D
,--data-file
-b
,--binary
-B
,--binary-file
-m
,--metadata
-M
,--metadata-file
--stream-interval
--stream-call-duration
--stream-call-count
--stream-dynamic-messages
--reflect-metadata
--max-recv-message-size
--max-send-message-size
-o
,--output
-O
,--format
--skipFirst
--connections
--connect-timeout
--keepalive
--name
--tags
--cpus
--debug
-e
,--enable-compression
--count-errors
-v
,--version
-h
,--help
-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.
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:
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:
-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.
-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.
-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.
-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:
-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.
-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.
-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:
msg1 := &helloworld.HelloRequest{}
msg1.Name = "Alice"
msg2 := &helloworld.HelloRequest{}
msg2.Name = "Bob"
buf := proto.Buffer{}
_ = buf.EncodeMessage(msg1)
_ = buf.EncodeMessage(msg2)
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:
--stream-call-count=2 -d '[{"name":"Joe"},{"name":"Kate"},{"name":"Sara"}]'
Will cause only [{"name":"Joe"},{"name":"Kate"}]
to be sent. Similarly:
--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:
--stream-dynamic-messages=true --stream-call-count=5 -d '{"name":"{{randomString 8 }}"}'
Will result in streaming call with the following data sent:
[{"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.
--stream-call-count=5 -d '{"name":"{{randomString 8 }}"}'
Results in the following data sent:
[{"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.
ghz --insecure \
--proto ./protos/greeter.proto \
--call helloworld.Greeter.SayHello \
-d '{"name":"Joe"}' -c 5 -n 50 -m '{"request-id":"{{.RequestNumber}}", "timestamp":"{{.TimestampUnix}}"}' \
--debug ./logs/debug.json \
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).