package module
v0.8.0 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Jul 26, 2018 License: Apache-2.0 Imports: 22 Imported by: 0




build status Go Report Card

Simple gRPC benchmarking and load testing tool inspired by hey and grpcurl.


Download a prebuilt executable binary from the releases page.


Usage: ghz [options...] <host>
  -proto	The protocol buffer file.
  -protoset	The compiled protoset file. Alternative to proto. -proto takes precedence.
  -call		A fully-qualified method name in 'service/method' or 'service.method' format.
  -cert		The file containing the CA root cert file.
  -cname	An override of the expect Server Cname presented by the server.
  -config	Path to the config JSON file.

  -c  Number of requests to run concurrently. Total number of requests cannot
	  be smaller than the concurrency level. Default is 50.
  -n  Number of requests to run. Default is 200.
  -q  Rate limit, in queries per second (QPS). Default is no rate limit.
  -t  Timeout for each request in seconds. Default is 20, use 0 for infinite.
  -z  Duration of application to send requests. When duration is reached,
      application stops and exits. If duration is specified, n is ignored.
      Examples: -z 10s -z 3m.
  -x  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 -x 3m.

  -d  The call data as stringified JSON.
  -D  Path for call data JSON file. For example, /home/user/file.json or ./file.json.
  -m  Request metadata as stringified JSON.
  -M  Path for call metadata JSON file. For example, /home/user/metadata.json or ./metadata.json.

  -o  Output path. If none provided stdout is used.
  -O  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.

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

  -T  Connection timeout in seconds for the initial connection dial. Default is 10.
  -L  Keepalive time in seconds. Only used if present and above 0.

  -cpus		Number of used cpu cores. (default for current machine is 8 cores)

  -v  Print the version.

Alternatively all settings can be set via ghz.json file if present in the same path as the ghz executable. A custom configuration file can be specified using -config option.

Call Template Data

Data and metadata can specify template actions that will be parsed and evaluated at every request. Each request gets a new instance of the data. The available variables / actions are:

// call template data
type callTemplateData struct {
	RequestNumber      int64  // unique incrememnted request number for each request
	FullyQualifiedName string // fully-qualified name of the method call
	MethodName         string // shorter call method name
	ServiceName        string // the service name
	InputName          string // name of the input message type
	OutputName         string // name of the output message type
	IsClientStreaming  bool   // whether this call is client streaming
	IsServerStreaming  bool   // whether this call is server streaming
	Timestamp          string // timestamp of the call in RFC3339 format
	TimestampUnix      int64  // timestamp of the call as unix time

This can be useful to inject variable information into the data or metadata payload for each request, such as timestamp or unique request number. See examples below.


A simple unary call:

ghz -proto ./greeter.proto -call helloworld.Greeter.SayHello -d '{"name":"Joe"}'

A simple unary call with metadata using template actions:

ghz -proto ./greeter.proto -call helloworld.Greeter.SayHello -d '{"name":"Joe"}' -m '{"trace_id":"{{.RequestNumber}}","timestamp":"{{.TimestampUnix}}"}'

Custom number of requests and concurrency:

ghz -proto ./greeter.proto -call helloworld.Greeter.SayHello -d '{"name":"Joe"}' -n 2000 -c 20

Client streaming data can be sent as an array, each element representing a single message:

ghz -proto ./greeter.proto -call helloworld.Greeter.SayHelloCS -d '[{"name":"Joe"},{"name":"Kate"},{"name":"Sara"}]'

If a single object is given for data it is sent as every message.

We can also use .protoset files which can bundle multiple protoco buffer files into one binary file.

Create a protoset

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

And then use it as input to ghz with -protoset option:

./ghz -protoset ./bundle.protoset -call helloworld.Greeter.SayHello -d '{"name":"Bob"}' -n 1000 -c 10

Note that only one of -proto or -protoset options will be used. -proto takes precedence.

Using a custom config file:

ghz -config ./config.json

Example ghz.json

    "proto": "/path/to/greeter.proto",
    "call": "helloworld.Greeter.SayHello",
    "n": 2000,
    "c": 50,
    "d": {
        "name": "Joe"
    "m": {
        "foo": "bar",
        "trace_id": "{{.RequestNumber}}",
        "timestamp": "{{.TimestampUnix}}"
    "i": [
    "n": 4000,
    "c": 40,
    "x": "10s",
    "host": ""


Sample standard output of summary of the results:

  Count:	2000
  Total:	345.52 ms
  Slowest:	15.41 ms
  Fastest:	0.66 ms
  Average:	6.83 ms
  Requests/sec:	5788.35

Response time histogram:
  0.664 [1]	|
  2.138 [36]	|∎
  3.613 [14]	|
  5.087 [65]	|∎∎
  6.561 [1305]	|∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
  8.035 [274]	|∎∎∎∎∎∎∎∎
  9.509 [66]	|∎∎
  10.983 [0]	|
  12.458 [59]	|∎∎
  13.932 [130]	|∎∎∎∎
  15.406 [50]	|∎∎

Latency distribution:
  10% in 5.18 ms
  25% in 5.51 ms
  50% in 6.10 ms
  75% in 6.72 ms
  90% in 12.19 ms
  95% in 13.26 ms
  99% in 14.73 ms
Status code distribution:
  [OK]	2000 responses

Alternatively with -O csv flag we can get detailed listing in csv format:

duration (ms),status,error

HTML output can be generated using html as format in the -O option. See sample output.

Using -O json outputs JSON data, and -O pretty outputs JSON in pretty format.


Icon made by Freepik from is licensed by CC 3.0 BY





Package ghz provides gRPC benchmarking functionality



This section is empty.


This section is empty.


This section is empty.


type Bucket

type Bucket struct {
	// The Mark for histogram bucket in seconds
	Mark float64 `json:"mark"`

	// The count in the bucket
	Count int `json:"count"`

	// The frequency of results in the bucket as a decimal percentage
	Frequency float64 `json:"frequency"`

Bucket holds histogram data

type LatencyDistribution

type LatencyDistribution struct {
	Percentage int           `json:"percentage"`
	Latency    time.Duration `json:"latency"`

LatencyDistribution holds latency distribution data

type Options

type Options struct {
	Host          string
	Cert          string
	CName         string
	N             int
	C             int
	QPS           int
	Z             time.Duration
	Timeout       int
	DialTimtout   int
	KeepaliveTime int
	Data          interface{}
	Metadata      *map[string]string

Options represents the request options

type Report

type Report struct {
	Count   uint64        `json:"count"`
	Total   time.Duration `json:"total"`
	Average time.Duration `json:"average"`
	Fastest time.Duration `json:"fastest"`
	Slowest time.Duration `json:"slowest"`
	Rps     float64       `json:"rps"`

	ErrorDist      map[string]int `json:"errorDistribution"`
	StatusCodeDist map[string]int `json:"statusCodeDistribution"`

	LatencyDistribution []LatencyDistribution `json:"latencyDistribution"`
	Histogram           []Bucket              `json:"histogram"`
	Details             []ResultDetail        `json:"details"`

Report holds the data for the full test

type Reporter

type Reporter struct {
	// contains filtered or unexported fields

Reporter gethers all the results

func (*Reporter) Finalize

func (r *Reporter) Finalize(total time.Duration) *Report

Finalize all the gathered data into a final report

func (*Reporter) Run

func (r *Reporter) Run()

Run runs the reporter

type Requester

type Requester struct {
	// contains filtered or unexported fields

Requester is used for doing the requests

func New

func New(mtd *desc.MethodDescriptor, c *Options) (*Requester, error)

New creates new Requester

func (*Requester) Finish

func (b *Requester) Finish() *Report

Finish finishes the test run

func (*Requester) Run

func (b *Requester) Run() (*Report, error)

Run makes all the requests and returns a report of results It blocks until all work is done.

func (*Requester) Stop

func (b *Requester) Stop()

Stop stops the test

type ResultDetail

type ResultDetail struct {
	Latency time.Duration `json:"latency"`
	Error   string        `json:"error"`
	Status  string        `json:"status"`

ResultDetail data for each result


Path Synopsis
Package helloworld is a generated protocol buffer package.
Package helloworld is a generated protocol buffer package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL