Skip to main content
Version: 6.0.0

Reports & Workflow

Stroppy v6 records metrics with OpenTelemetry instruments inside the Go engine. Every run prints a terminal summary; optional OTLP export sends the same measurements to a collector.

Terminal summary​

At shutdown Stroppy collects counters, gauges, and fixed-bucket histograms:

=== bench summary ===
iterations_total 100.000
transactions_total 100.000
run_query_operations_total 500.000
run_query_duration count=500 avg=1.240 p(50)~=1.000 p(90)~=2.500 p(95)~=2.500 p(99)~=5.000
tx_total_duration count=100 avg=7.310 p(50)~=5.000 p(90)~=10.000 p(95)~=10.000 p(99)~=25.000

Histogram percentiles are approximations from fixed buckets. Duration histograms use milliseconds and include buckets from 5 microseconds through 60 seconds. This keeps memory bounded during long high-throughput runs.

Core metrics​

MetricInstrumentMeaning
iterations_totalcounterCompleted iterations.
iteration_durationhistogramEnd-to-end iteration duration in ms.
transactions_totalcounterTransactions observed.
tx_total_durationhistogramTransaction wall time in ms.
tx_commits_totalcounterSuccessful commits.
tx_errors_totalcounterTransaction errors.
tx_queries_per_txhistogramQueries per transaction.
run_query_operations_totalcounterQuery operations.
run_query_errors_totalcounterQuery errors.
run_query_durationhistogramQuery execution time in ms.
insert_operations_totalcounterInsert requests.
insert_errors_totalcounterFailed insert requests.
insert_durationhistogramInsert duration in ms.
insert_rows_totalcounterLoaded rows.
insert_progress_rows_totalcounterRows reported by progress events.
insert_progress_rows_per_secondgaugeCurrent progress throughput.
terminal_errors_totalcounterTerminal nonfatal workload errors.
failed_iterations_totalcounterIterations ending in terminal error.
failed_queries_totalcounterQuery-set operations ending in error.
retry_attempts_totalcounterScheduled retries.

Workloads add their own instruments. TPC-C, for example, records transaction counts, per-type duration histograms, mix decisions, remote selections, rollback checks, and retries. TPC-H records duration, run, error, and elapsed-total metrics for q1 through q22.

Completed-with-errors summary​

Nonfatal terminal transaction and query-set errors do not stop remaining work. When any occur, final output adds:

=== bench completed with errors ===
terminal_errors_total 3
failed_iterations_total 1
failed_queries_total 2
retry_attempts_total 4
representative error groups:
operation=... class=... count=...

Warnings are bounded by operation/error-class group; repeated failures are reported periodically instead of flooding logs.

A nonfatal completed-with-errors run exits 0. Automation requiring a clean benchmark should gate on terminal_errors_total, failed counters, or the final marker. Structural setup/validation/teardown/fatal failures remain nonzero.

Workload reports​

TPC-C prints a workload-specific text report after every run. JSON is also available to programmatic callers inside the Go workload package. It includes:

  • count, mix, and throughput per transaction type;
  • p50/p90/p95/p99 response times;
  • retry and required rollback/remote-choice observations;
  • TPC-C §5.2.5 response-time and mix verdicts for paced runs;
  • statistical-validity and steady-state status.

Unpaced throughput runs mark compliance checks not applicable rather than presenting them as specification results.

TPC-H and TPC-DS SF=1 answer comparison is diagnostic. Differences and query errors appear in their validation summaries but do not change exit status.

OpenTelemetry export​

Configure OTLP under global.exporter.otlpExport in a JSON config file.

gRPC​

{
"global": {
"exporter": {
"name": "otlp",
"otlpExport": {
"otlpGrpcEndpoint": "otel-collector:4317",
"otlpEndpointInsecure": true,
"otlpMetricsPrefix": "stroppy_"
}
}
}
}

HTTP​

{
"global": {
"exporter": {
"name": "otlp",
"otlpExport": {
"otlpHttpEndpoint": "otel-collector:4318",
"otlpHttpExporterUrlPath": "/v1/metrics",
"otlpHeaders": "authorization=Bearer token",
"otlpEndpointInsecure": true
}
}
}
}

Endpoint fields use host:port without a URL scheme. If both endpoints are configured, gRPC wins. Default metric prefix is stroppy_; default HTTP path is /v1/metrics.

OTEL_METRIC_EXPORT_INTERVAL sets export cadence in milliseconds; default is 10000.

Resource attributes include service.name=stroppy, release version, stroppy.run.id when configured, and every entry from global.metadata. Core metric attributes include:

step
table_name
method
event
row_kind
tx_name
tx_isolation
tx_action
operation
error_class

Attribute cardinality is bounded. Excess unseen tag combinations collapse into an overflow series.

Grafana dashboard​

Stroppy ships a dashboard for the v6 metric model:

Import it into Grafana and point panels at metrics received from your OTLP collector/export path. The collector exposes service.name as job in the reference integration setup. Add a scenario entry under global.metadata if you want to use the dashboard's scenario filter:

{"global": {"metadata": {"scenario": "tpcc"}}}

V6 does not emit the old client byte counters, so dashboard network panels stay empty. Load, query, transaction, error, and progress panels use current native metrics.

Repeatable benchmark workflow​

1. Record environment​

Pin:

  • Stroppy version;
  • workload, SQL variant, scale, and seed;
  • database version/configuration;
  • machine placement and hardware;
  • executor, VUs, duration/iterations;
  • driver pool and load workers.

Save repeatable inputs in JSON:

{
"script": "tpcc/tx",
"drivers": {
"0": {
"driverType": "postgres",
"url": "postgres://db:5432/tpcc",
"pool": {"maxConns": 64}
}
},
"run": {
"executor": "constant-vus",
"vus": 64,
"duration": "10m"
},
"params": {
"scaleFactor": 50,
"loadWorkers": 16
}
}

2. Separate load and measurement​

stroppy run -f benchmark.json --no-steps workload
stroppy run -f benchmark.json --steps workload

This removes schema/load time from workload throughput. Keep loaded data and configuration identical between comparisons.

3. Warm and repeat​

Run enough repetitions to distinguish change from noise. Record medians and distributions, not one best result. Keep database cache state intentional and consistent.

4. Inspect errors before performance​

A high throughput number is invalid when terminal errors, failed queries, failed iterations, or unexpected retries differ between runs. Compare error summary first.

5. Correlate server telemetry​

Use database and host metrics alongside Stroppy measurements. A client-side latency change can originate in connection pooling, query count, network, database CPU, I/O, locks, or plan changes.

Measure Stroppy overhead​

Run Machine Baseline on each load-generator host:

stroppy baseline

The wire tier gives a client-side ceiling for comparison with real database runs. Saved JSON history tracks machine-local changes across Stroppy versions.

CI usage​

A strict smoke job should fail on command exit, error logs, and the nonfatal summary marker:

set -euo pipefail
stroppy run tpcb/tx -f smoke.json 2>&1 | tee stroppy.log
if grep -q 'bench completed with errors' stroppy.log; then
exit 1
fi

For production performance gates, export OTLP and compare stable aggregate windows on dedicated runners. Avoid hard absolute thresholds across unrelated hardware.