otelbench
April 1, 2026 ยท View on GitHub
otelbench wraps the collector inside a Go test benchmark. It outputs throughput numbers in standard Go benchmark format. It uses a collector config yaml as a base, and applies some overrides from command line options.
Usage
Usage of ./otelbench:
-api-key string
API key for target server
-concurrency list
comma-separated list of concurrency (number of simulated agents) to run each benchmark with. Supports numeric values (e.g., "1,4,8"), "auto" to use available CPU cores, or "auto:Nx" for multipliers (e.g., "auto:2x" for double, "auto:0.5x" for half)
-config string
path to collector config yaml. If empty, the config.yaml embedded in the binary will be used.
-endpoint value
target server endpoint for both otlp and otlphttp exporters (default to value in config yaml), equivalent to setting both -endpoint-otlp and -endpoint-otlphttp
-endpoint-otlp value
target server endpoint for otlp exporter (default to value in config yaml)
-endpoint-otlphttp value
target server endpoint for otlphttp exporter (default to value in config yaml)
-exporter-otlp
benchmark exporter otlp (default true)
-exporter-otlphttp
benchmark exporter otlphttp (default true)
-header value
extra headers in key=value format when sending data to the server. Can be repeated. e.g. -header X-FIRST-HEADER=foo -header X-SECOND-HEADER=bar
-insecure
disable TLS, ignored by otlphttp exporter (default to value in config yaml)
-insecure-skip-verify
skip validating the remote server TLS certificates (default to value in config yaml)
-logs
benchmark logs (default true)
-logs-data-path string
path to logs data file (e.g. logs.json). If empty, embedded data will be used.
-metrics
benchmark metrics (default true)
-metrics-data-path string
path to metrics data file (e.g. metrics.json). If empty, embedded data will be used.
-profiles
benchmark profiles (default false)
-profiles-data-path string
path to profiles data file (e.g. profiles.json). If empty, embedded data will be used.
-mixed
benchmark mixed signals, i.e. logs, metrics, traces and profiles at the same time (default true)
-secret-token string
secret token for target server
-shuffle
shuffle the order of benchmarks. This is useful for concurrent runs.
-telemetry-elasticsearch-api-key string
optional remote Elasticsearch telemetry API key
-telemetry-elasticsearch-index string
optional remote Elasticsearch telemetry metrics index pattern (default "metrics-*")
-telemetry-elasticsearch-password string
optional remote Elasticsearch telemetry password
-telemetry-elasticsearch-timeout duration
optional remote Elasticsearch telemetry request timeout (default 1m0s)
-telemetry-elasticsearch-url list
optional comma-separated list of remote Elasticsearch telemetry hosts
-telemetry-elasticsearch-username string
optional remote Elasticsearch telemetry username
-telemetry-filter-cluster-name string
optional remote Elasticsearch telemetry cluster name metrics filter
-telemetry-filter-project-id string
optional remote Elasticsearch telemetry project id metrics filter
-telemetry-metrics list
optional comma-separated list of remote Elasticsearch telemetry metrics to be reported (default otelcol_process_cpu_seconds,otelcol_process_memory_rss,otelcol_process_runtime_total_alloc_bytes,otelcol_process_runtime_total_sys_memory_bytes,otelcol_process_uptime)
-test.bench regexp
run only benchmarks matching regexp
-test.benchmem
print memory allocations for benchmarks
-test.benchtime d
run each benchmark for duration d or N times if `d` is of the form Nx (default 1s)
-test.blockprofile file
write a goroutine blocking profile to file
-test.blockprofilerate rate
set blocking profile rate (see runtime.SetBlockProfileRate) (default 1)
-test.count n
run tests and benchmarks n times (default 1)
-test.coverprofile file
write a coverage profile to file
-test.cpu list
comma-separated list of cpu counts to run each test with
-test.cpuprofile file
write a cpu profile to file
-test.failfast
do not start new tests after the first test failure
-test.fullpath
show full file names in error messages
-test.fuzz regexp
run the fuzz test matching regexp
-test.fuzzcachedir string
directory where interesting fuzzing inputs are stored (for use only by cmd/go)
-test.fuzzminimizetime value
time to spend minimizing a value after finding a failing input (default 1m0s)
-test.fuzztime value
time to spend fuzzing; default is to run indefinitely
-test.fuzzworker
coordinate with the parent process to fuzz random values (for use only by cmd/go)
-test.gocoverdir string
write coverage intermediate files to this directory
-test.list regexp
list tests, examples, and benchmarks matching regexp then exit
-test.memprofile file
write an allocation profile to file
-test.memprofilerate rate
set memory allocation profiling rate (see runtime.MemProfileRate)
-test.mutexprofile string
write a mutex contention profile to the named file after execution
-test.mutexprofilefraction int
if >= 0, calls runtime.SetMutexProfileFraction() (default 1)
-test.outputdir dir
write profiles to dir
-test.paniconexit0
panic on call to os.Exit(0)
-test.parallel n
run at most n tests in parallel (default 16)
-test.run regexp
run only tests and examples matching regexp
-test.short
run smaller test suite to save time
-test.shuffle string
randomize the execution order of tests and benchmarks (default "off")
-test.skip regexp
do not list or run tests matching regexp
-test.testlogfile file
write test action log to file (for use only by cmd/go)
-test.timeout d
panic test binary after duration d (default 0, timeout disabled)
-test.trace file
write an execution trace to file
-test.v
verbose: print additional output
-traces
benchmark traces (default true)
-traces-data-path string
path to traces data file (e.g. traces.json). If empty, embedded data will be used.
Example usage
It is recommended to explicitly configure concurrency to roughly the number of threads of the system running otelbench. Otherwise, concurrency will default to 1, and load generation will be single threaded and will send to target with only 1 connection, resulting in an underestimated throughput.
To send to a local apm-server
./otelbench -config=./config.yaml -endpoint=http://localhost:8200 -secret-token=foobar -insecure
To send to an ESS apm-server
./otelbench -test.benchtime=1m -config=./config.yaml -endpoint=https://foobar.apm.europe-west2.gcp.elastic-cloud.com:443 -api-key=some_api_key
To send to an OTel collector with a special otlphttp path
./otelbench -config=./config.yaml -endpoint-otlp=http://localhost:4317 -endpoint-otlphttp=https://localhost:4318/prefix -api-key some_api_key
It is possible to run with a customized config to avoid passing in command line options every time
./otelbench -config=./my-custom-config.yaml
Optional remote OTel collector metrics will be reported as bench stats when additional telemetry flags are provided. Gauge metrics will be aggregated to average, while Counter and Histogram will be aggregated to sum. For the full list of reported metrics see https://opentelemetry.io/docs/collector/internal-telemetry/#basic-level-metrics.
./otelbench -config=./config.yaml -endpoint-otlp=localhost:4317 -endpoint-otlphttp=https://localhost:4318/prefix -api-key some_api_key -telemetry-elasticsearch-url=localhost:9200 -telemetry-elasticsearch-api-key telemetry_api_key -telemetry-elasticsearch-index "metrics*" -telemetry-filter-cluster-name cluster_name
Example usage with Docker image
Basic usage
docker run -it docker.elastic.co/observability-ci/otelbench:v0.6.0 -endpoint-otlp=http://172.17.0.1:4317 -api-key some_api_key -insecure
Remember that localhost does not work because otelbench runs in a container. Use 172.17.0.1 for Linux and host.docker.internal for macOS.
Advanced usage with custom config file
docker run -it --volume /path/to/config.yaml:/config.yaml docker.elastic.co/observability-ci/otelbench:v0.6.0 -endpoint-otlp=http://172.17.0.1:4317 -api-key some_api_key -insecure -config=/config.yaml
Contribute
If you want to contribute to any go files, you need to create a changelog entry:
- Create a changelog entry by running
make chlog-new. - Validate your changelog entry by running
make chlog-validate. - If you want to preview the future
CHANGELOG.mdyou can also runmake chlog-preview.
Create new release
There are two ways you can trigger a new release:
- Manually, by triggering the GH actions workflow
bump-otelbench. - Automatically, by updating the VERSION field in the Makefile.
The bump-otelbench workflow will check the new version increased in regards to the previous version.
If it did, then a new PR will be opened, updating the CHANGELOG file and removing
the changelog fragments.
Once this PR has been merged, a new workflow, release-otelbench will be triggered. The otelbench image
is built and pushed to docker.elastic.co/observability-ci/otelbench registry. The new image should have
as a tag the newest otelbench version.