{"id":13526587,"url":"https://github.com/yarpc/yab","last_synced_at":"2026-01-11T23:03:14.527Z","repository":{"id":37431763,"uuid":"53321582","full_name":"yarpc/yab","owner":"yarpc","description":"Call and benchmark YARPC services from the command line.","archived":false,"fork":false,"pushed_at":"2025-09-01T13:04:04.000Z","size":1111,"stargazers_count":87,"open_issues_count":43,"forks_count":38,"subscribers_count":15,"default_branch":"dev","last_synced_at":"2025-09-01T13:28:15.052Z","etag":null,"topics":["benchmarking","cli","curl","yarpc"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yarpc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2016-03-07T11:48:58.000Z","updated_at":"2025-09-01T11:21:47.000Z","dependencies_parsed_at":"2024-01-13T21:38:35.777Z","dependency_job_id":"6cfeb6ae-87f5-4503-b60b-ff4d7b679b9f","html_url":"https://github.com/yarpc/yab","commit_stats":null,"previous_names":["uber/tbench","uber/yab"],"tags_count":36,"template":false,"template_full_name":null,"purl":"pkg:github/yarpc/yab","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yarpc%2Fyab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yarpc%2Fyab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yarpc%2Fyab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yarpc%2Fyab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yarpc","download_url":"https://codeload.github.com/yarpc/yab/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yarpc%2Fyab/sbom","scorecard":{"id":485428,"data":{"date":"2025-07-07","repo":{"name":"github.com/yarpc/yab","commit":"a69516f33e98953696847d0fdbb484328bb187d1"},"scorecard":{"version":"v5.2.1-18-gbb9c347d","commit":"bb9c347dff6349d986baab6578a46d68a5524c62"},"score":3.8,"checks":[{"name":"Code-Review","score":9,"reason":"Found 16/17 approved changesets -- score normalized to 9","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#packaging"}},{"name":"Maintained","score":3,"reason":"3 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/go.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.24.0 not signed: https://api.github.com/repos/yarpc/yab/releases/196938677","Warn: release artifact v0.23.0 not signed: https://api.github.com/repos/yarpc/yab/releases/160248655","Warn: release artifact v0.22.0 not signed: https://api.github.com/repos/yarpc/yab/releases/93791595","Warn: release artifact v0.21.0 not signed: https://api.github.com/repos/yarpc/yab/releases/48903738","Warn: release artifact v0.20.0 not signed: https://api.github.com/repos/yarpc/yab/releases/43156887","Warn: release artifact v0.24.0 does not have provenance: https://api.github.com/repos/yarpc/yab/releases/196938677","Warn: release artifact v0.23.0 does not have provenance: https://api.github.com/repos/yarpc/yab/releases/160248655","Warn: release artifact v0.22.0 does not have provenance: https://api.github.com/repos/yarpc/yab/releases/93791595","Warn: release artifact v0.21.0 does not have provenance: https://api.github.com/repos/yarpc/yab/releases/48903738","Warn: release artifact v0.20.0 does not have provenance: https://api.github.com/repos/yarpc/yab/releases/43156887"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":2,"reason":"dependency not pinned by hash detected -- score normalized to 2","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/yarpc/yab/go.yml/dev?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/yarpc/yab/go.yml/dev?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/yarpc/yab/go.yml/dev?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/go.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/yarpc/yab/go.yml/dev?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/yarpc/yab/go.yml/dev?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/yarpc/yab/go.yml/dev?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:60: update your workflow using https://app.stepsecurity.io/secureworkflow/yarpc/yab/go.yml/dev?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1: pin your Docker image by updating golang:1.7-alpine to golang:1.7-alpine@sha256:3f79ea057ef12518935ad981f62637d046a033eb10d28d5203c048837fedee58","Warn: goCommand not pinned by hash: Dockerfile:8","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   1 out of   2 goCommand dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"18 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-r4m4-pmvw-m6j5","Warn: Project is vulnerable to: GO-2021-0101","Warn: Project is vulnerable to: GO-2021-0053 / GHSA-c3h9-896r-86jm","Warn: Project is vulnerable to: GO-2022-0322 / GHSA-cg3q-j54f-5p7p","Warn: Project is vulnerable to: GO-2022-0969 / GHSA-69cg-p879-7622","Warn: Project is vulnerable to: GO-2022-1144 / GHSA-xrjj-mj9h-534m","Warn: Project is vulnerable to: GO-2023-1571 / GHSA-vvpx-j8f3-3w6h","Warn: Project is vulnerable to: GO-2023-1988 / GHSA-2wrh-6pvc-2jm9","Warn: Project is vulnerable to: GO-2023-2102 / GHSA-4374-p667-p6c8","Warn: Project is vulnerable to: GO-2023-2153 / GHSA-m425-mq94-257g / GHSA-qppj-fm5r-hxr3","Warn: Project is vulnerable to: GO-2024-2687 / GHSA-4v7x-pqxf-cx7m","Warn: Project is vulnerable to: GO-2024-3333","Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw","Warn: Project is vulnerable to: GO-2022-0493 / GHSA-p782-xgp4-8hr8","Warn: Project is vulnerable to: GO-2022-1059 / GHSA-69ch-w2m2-3vjp","Warn: Project is vulnerable to: GO-2024-2611 / GHSA-8r3f-844c-mc37","Warn: Project is vulnerable to: GO-2022-0603 / GHSA-hp87-p4gw-j4gq"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T17:38:33.568Z","repository_id":37431763,"created_at":"2025-08-19T17:38:33.569Z","updated_at":"2025-08-19T17:38:33.569Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28326166,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T22:11:01.104Z","status":"ssl_error","status_checked_at":"2026-01-11T22:10:58.990Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["benchmarking","cli","curl","yarpc"],"created_at":"2024-08-01T06:01:31.873Z","updated_at":"2026-01-11T23:03:14.511Z","avatar_url":"https://github.com/yarpc.png","language":"Go","funding_links":[],"categories":["Go","cli"],"sub_categories":[],"readme":"# yab [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]\n\n`yab` (Yet Another Benchmarker) is a tool to benchmark YARPC services. It\ncurrently supports making Thrift requests to both HTTP and [TChannel](https://github.com/uber/tchannel) services, as well as Protobuf requests to [gRPC](https://grpc.io/) services.\n\n`yab` is currently in **beta** status.\n\n\n### Installing\n\nIf you have go installed, simply run the following to install the latest version:\n```bash\nGO111MODULE=on go get -u github.com/yarpc/yab\n```\n\nThis will install `yab` to `$GOPATH/bin/yab`.\n\nOptionally, you can get precompiled binaries from [Releases][releases].\n\n### Usage\n\n```\nUsage:\n  yab [\u003cservice\u003e \u003cmethod\u003e \u003cbody\u003e] [OPTIONS]\n\nyab is a benchmarking tool for TChannel and HTTP applications. It's primarily\nintended for Thrift applications but supports other encodings like JSON and\nbinary (raw). It can be used in a curl-like fashion when benchmarking features\nare disabled.\n\nyab includes a full man page (man yab), which is also available online:\nhttp://yarpc.github.io/yab/man.html\n\n\nApplication Options:\n  -v                             Enable more detailed logging. Repeats increase\n                                 the verbosity, ie. -vvv\n      --version                  Displays the application version\n\nRequest Options:\n  -e, --encoding=                The encoding of the data, options are: Thrift,\n                                 proto, JSON, raw. Defaults to Thrift if the\n                                 method contains '::' or a Thrift file is\n                                 specified. Defaults to proto if the method\n                                 contains '/' or a proto filedescriptorset is\n                                 specified\n  -t, --thrift=                  Path of the .thrift file\n  -F, --file-descriptor-set-bin= A binary file containing a compiled protobuf\n                                 FileDescriptorSet.\n      --procedure=               The full method name to invoke (Thrift:\n                                 Svc::Method, Proto: package.Service/Method).\n  -m, --method=                  Alias for procedure\n  -r, --request=                 The request body, in JSON or YAML format\n  -f, --file=                    Path of a file containing the request body in\n                                 JSON or YAML\n  -H, --header=                  Individual application header as a key:value\n                                 pair per flag\n      --headers=                 The headers in JSON or YAML format\n      --headers-file=            Path of a file containing the headers in JSON\n                                 or YAML\n  -B, --baggage=                 Individual context baggage header as a\n                                 key:value pair per flag\n      --health                   Hit the health endpoint, Meta::health\n      --timeout=                 The timeout for each request. E.g., 100ms,\n                                 0.5s, 1s. If no unit is specified,\n                                 milliseconds are assumed. (default: 1s)\n  -y, --yaml-template=           Send a tchannel request specified by a YAML\n                                 template\n  -A, --arg=                     A list of key-value template arguments,\n                                 specified as -A foo:bar -A user:me\n      --disable-thrift-envelope  Disables Thrift envelopes (disabled by default\n                                 for TChannel and gRPC)\n      --multiplexed-thrift       Enables the Thrift TMultiplexedProtocol used\n                                 by services that host multiple Thrift services\n                                 on a single endpoint.\n      --stream-interval=         Interval between consecutive stream message sends,\n                                 applicable separately to every stream request\n                                 opened on a connection.\n      --stream-delay-close-send= Delay the closure of send stream once all the\n                                 request messages have been sent.\n\nTransport Options:\n  -s, --service=                 The TChannel/Hyperbahn service name\n  -p, --peer=                    The host:port of the service to call\n  -P, --peer-list=               Path or URL of a JSON, YAML, or flat file\n                                 containing a list of host:ports. -P? for\n                                 supported protocols.\n      --caller=                  Caller will override the default caller name\n                                 (which is yab-$USER).\n      --rk=                      The routing key overrides the service name\n                                 traffic group for proxies.\n      --rd=                      The routing delegate overrides the routing key\n                                 traffic group for proxies.\n      --sk=                      The shard key is a transport header that clues\n                                 where to send a request within a clustered\n                                 traffic group.\n      --jaeger                   Use the Jaeger tracing client to send Uber\n                                 style traces and baggage headers\n      --force-jaeger-sample      If Jaeger tracing is enabled with --jaeger, force all requests\n                                 to be sampled.\n  -T, --topt=                    Transport options for TChannel, protocol\n                                 headers for HTTP\n      --http-method=             The HTTP method to use (default: POST)\n      --grpc-max-response-size=  Maximum response size for gRPC requests. Default value is 4MB\n\nBenchmark Options:\n  -n, --max-requests=            The maximum number of requests to make. 0\n                                 implies no limit. (default: 0)\n  -d, --max-duration=            The maximum amount of time to run the\n                                 benchmark for. 0 implies no duration limit.\n                                 (default: 0s)\n      --cpus=                    The number of OS threads\n      --connections=             The number of TCP connections to use\n      --warmup=                  The number of requests to make to warmup each\n                                 connection (default: 10)\n      --concurrency=             The number of concurrent calls per connection\n                                 (default: 1)\n      --rps=                     Limit on the number of requests per second.\n                                 The default (0) is no limit. (default: 0)\n      --statsd=                  Optional host:port of a StatsD server to\n                                 report metrics\n      --per-peer-stats           Whether to emit stats by peer rather than\n                                 aggregated\n\nHelp Options:\n  -h, --help                     Show this help message\n```\n\n### Making a single request\n#### Thrift\nThe following examples assume that the Thrift service running looks like:\n```thrift\nservice KeyValue {\n  string get(1: string key)\n}\n```\n\nIf a TChannel service was running with name `keyvalue` on `localhost:12345`, you can\nmake a call to the `get` method by running:\n\n```bash\nyab -t ~/keyvalue.thrift -p localhost:12345 keyvalue KeyValue::get -r '{\"key\": \"hello\"}'\n```\n\n#### Proto\nThe following examples assume that the Proto service running looks like:\n```proto\nservice KeyValue {\n  rpc GetValue(Request) returns (Response) {}\n  rpc GetValueStream(stream Request) returns (stream Response) {}\n}\n\nmessage Request {\n    required string key = 1;\n}\n\nmessage Response {\n    required string value = 1;\n}\n```\n\nIf a gRPC service was running with name `KeyValue` on `localhost:12345` with proto package name `pkg.keyvalue` and \nbinary file containing a compiled protobuf FileDescriptorSet as `keyValue.proto.bin`, you can\nmake a call to the `GetValue` method by running:\n\n```bash\nyab keyvalue pkg.keyvalue/GetValue --file-descriptor-set-bin=keyValue.proto.bin -r '{\"key\": \"hello\"}' -p localhost:12345\n```\n\nYou can make a call to the bi-directional stream method `GetValueStream` with multiple requests by running:\n```bash\nyab keyvalue pkg.keyvalue/GetValueStream --file-descriptor-set-bin=keyValue.proto.bin -r '{\"key\": \"hello1\"} {\"key\": \"hello2\"}' -p localhost:12345\n```\n\nYou can also interactively pass request data (JSON or YAML) on STDIN to the bi-directional stream method `GetValueStream` by setting option `-request='-'`:\n\n```bash\nyab keyvalue pkg.keyvalue/GetValueStream --file-descriptor-set-bin=keyValue.proto.bin -r '-' -p localhost:12345\n\n{\"key\": \"hello1\"} // STDIN request-1\n{...} //Response-1\n\n{\"key\": \"hello2\"} // STDIN request-2\n{...} //Response-2\n```\nNote: YAML requests on STDIN must be delimited by `---` and followed by a newline.\n\nProtobuf FileDescriptorSet can be generated by running:\n```bash\nprotoc --include_imports --descriptor_set_out=keyValue.proto.bin keyValue.proto\n```\nNote : If [Server Reflection](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md) is enabled which provides information about publicly-accessible gRPC services on a server, then there is no need to specify the FileDescriptorSet binary:\n\n```bash\nyab keyvalue pkg.keyvalue/GetValue -r '{\"key\": \"hello\"} -p localhost:12345'\n```\n\n#### Specifying Peers\nA single `host:port` is specified using `-p`, but you can also specify multiple peers\nby passing the `-p` flag multiple times:\n```bash\nyab -t ~/keyvalue.thrift -p localhost:12345 -p localhost:12346 keyvalue KeyValue::get -r '{\"key\": \"hello\"}'\n```\n```bash\nyab keyvalue pkg.keyvalue/GetValue -r '{\"key\": \"hello\"} -p localhost:12345 -p localhost:12346'\n```\n\nIf you have a file containing a list of host:ports (either JSON or new line separated), you can\nspecify the file using `-P`:\n```bash\nyab -t ~/keyvalue.thrift -P ~/hosts.json keyvalue KeyValue::get -r '{\"key\": \"hello\"}'\n```\n```bash\nyab keyvalue pkg.keyvalue/GetValue -r '{\"key\": \"hello\"} -P ~/hosts.json'\n```\n\n`yab` also supports HTTP, instead of the peer being a single `host:port`, you would use a URL:\n```bash\nyab -t ~/keyvalue.thrift -p \"http://localhost:8080/rpc\" keyvalue KeyValue::get -r '{\"key\": \"hello\"}'\n```\n\n### Benchmarking\n\nTo benchmark an endpoint, you need all the command line arguments to describe the request,\nfollowed by benchmarking options. You need to set at least `--maxDuration` (or `-d`) to\nset the maximum amount of time to run the benchmark.\n\nYou can set values such as `3s` for 3 seconds, or `1m` for 1 minute. Valid time units are:\n * `ms` for milliseconds\n * `s` for seconds\n * `m` for minutes.\n\nYou can also control rate limit the benchmark (`--rps`), or customize the number of\nconnections (`--connections`) or control the amount of concurrent calls per\nconnection (`--concurrency`).\n\n```bash\nyab -t ~/keyvalue.thrift -p localhost:12345 keyvalue KeyValue::get -r '{\"key\": \"hello\"}' -d 5s --rps 100 --connections 4\n```\n\nIn a gRPC stream method benchmark, a stream benchmark request is considered successful when a stream sends all the requests and receives response messages successfully. Example stream benchmark command and output:\n```bash\n\u003e yab keyvalue pkg.keyvalue/GetValueStream -r '{\"key\": \"hello1\"} {\"key\": \"hello2\"}' -p localhost:12345 --duration=1s\n\nBenchmark parameters:\n  CPUs:            12\n  Connections:     24\n  Concurrency:     1\n  Max requests:    10000\n  Max duration:    1s\n  Max RPS:         0\nLatencies:\n  0.5000: 779.01µs\n  0.9000: 2.034852ms\n  0.9500: 2.932846ms\n  0.9900: 11.698821ms\n  0.9990: 15.839751ms\n  0.9995: 16.651223ms\n  1.0000: 17.198644ms\nElapsed time (seconds):         0.49\nTotal requests:                 10000\nRPS:                            20190.25\nTotal stream messages sent:     20000\nTotal stream messages received: 20000\n```\n\n[releases]: https://github.com/yarpc/yab/releases\n[ci-img]: https://travis-ci.com/yarpc/yab.svg?branch=master\n[ci]: https://travis-ci.com/yarpc/yab\n[cov-img]: https://codecov.io/gh/yarpc/yab/branch/master/graph/badge.svg\n[cov]: https://codecov.io/gh/yarpc/yab\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyarpc%2Fyab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyarpc%2Fyab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyarpc%2Fyab/lists"}