Bijecta.BenchmarkGate.Tool
0.4.0-alpha.1
dotnet tool install --global Bijecta.BenchmarkGate.Tool --version 0.4.0-alpha.1
dotnet new tool-manifest
dotnet tool install --local Bijecta.BenchmarkGate.Tool --version 0.4.0-alpha.1
#tool dotnet:?package=Bijecta.BenchmarkGate.Tool&version=0.4.0-alpha.1&prerelease
nuke :add-package Bijecta.BenchmarkGate.Tool --version 0.4.0-alpha.1
<div align="center"> <img src="./.github/assets/benchmarkgate-icon.svg" width="40" height="40" alt="BenchmarkGate" />
BenchmarkGate
A local-first performance contract gate for BenchmarkDotNet and CI.
</div>
Status: v0.4.0-alpha.1. See ROADMAP.md for what's
shipped and what's next.
What this is
BenchmarkGate turns BenchmarkDotNet output into an enforceable performance contract:
- No SaaS account, hosted database, or network connection required to evaluate benchmarks.
- Baselines and policies are plain, reviewable JSON files committed to your repository — a performance-budget change shows up in a pull-request diff, same as any other code change.
- Per-metric thresholds (mean time, allocation, ...) with separate warning and failure tiers, plus a stability gate that flags noisy measurements before they're evaluated as a regression.
- Runs identically locally and in CI.
Install
dotnet tool install --global Bijecta.BenchmarkGate.Tool --version 0.4.0-alpha.1
Quick start
benchmark-gate capture --results ./BenchmarkDotNet.Artifacts/results --output ./benchmarks/baseline.json --suite my-suite
benchmark-gate check --results ./BenchmarkDotNet.Artifacts/results --baseline ./benchmarks/baseline.json --policy ./benchmarks/policy.json
check reads BenchmarkDotNet's full-JSON output, compares it against the
committed baseline under the rules in policy.json, and exits non-zero the
moment a benchmark regresses past the failure threshold — a gate your
performance numbers have to pass before merge.
policy.json defines a stability gate and per-metric thresholds:
{
"schemaVersion": 1,
"stability": { "minimumMeasurements": 10, "maximumCoefficientOfVariation": 0.05 },
"metrics": {
"meanNanoseconds": { "direction": "lower-is-better", "warningPercent": 7.5, "failurePercent": 15, "minimumAbsoluteChange": 100 },
"allocatedBytesPerOperation": { "direction": "lower-is-better", "warningPercent": 1, "failurePercent": 5, "minimumAbsoluteChange": 1024 }
}
}
A benchmark whose measurements don't meet the stability bar is reported as
Unstable rather than evaluated as a pass or regression. A metric crossing
warningPercent but not failurePercent is reported as Warning — visible
in every report, and only affects the process exit code if you pass
--fail-on-warning.
Useful flags on check:
| Flag | Purpose |
|---|---|
--markdown <path> |
Write a GitHub-friendly Markdown summary |
--json <path> |
Write a machine-readable decision document |
--junit <path> |
Write a JUnit XML report for CI test-result UIs |
--fail-on-warning |
Make a Warning-only suite exit non-zero |
--quiet |
Suppress console output (reports/exit code still work) |
Comparing without a policy
benchmark-gate compare reports what changed between a baseline and a set
of results — matching, deltas, direction — without requiring a
policy.json or producing a pass/fail verdict. Useful for a quick "what
moved" check, a PR comment, or feeding a dashboard, when you don't want
check's policy machinery in the loop.
benchmark-gate compare --results ./BenchmarkDotNet.Artifacts/results --baseline ./benchmarks/baseline.json
Write a report to a file instead of stdout with --format and --output:
benchmark-gate compare --results ./BenchmarkDotNet.Artifacts/results --baseline ./benchmarks/baseline.json --format json --output ./compare.json
benchmark-gate compare --results ./BenchmarkDotNet.Artifacts/results --baseline ./benchmarks/baseline.json --format markdown --output ./compare.md
compare always exits 0 once it successfully produces a comparison — an
added benchmark, a removed benchmark, or a metric that got slower are
comparison results, not process failures. Use check when you need a
build to fail on regression.
Useful flags on compare:
| Flag | Purpose |
|---|---|
--format <console\|json\|markdown> |
Output format (default: console) |
--output <path> |
Write the report to a file instead of stdout. Required for --format json/--format markdown |
--quiet |
Suppress console output (an explicit --output file still gets written) |
Validating inputs
benchmark-gate validate checks a policy, baseline, and/or BenchmarkDotNet
results file for structural and semantic correctness, without evaluating
anything — useful for catching a malformed policy.json or a corrupted
results export before it fails a check run with a less specific error.
benchmark-gate validate --policy ./benchmarks/policy.json
benchmark-gate validate --baseline ./benchmarks/baseline.json
benchmark-gate validate --results ./BenchmarkDotNet.Artifacts/results
At least one of --policy, --baseline, --results is required; pass
multiple together to validate them all in one invocation:
benchmark-gate validate --policy ./benchmarks/policy.json --baseline ./benchmarks/baseline.json
Output groups diagnostics by source file, one line per finding, with a
stable machine-readable code (BGVxxx) you can search this repo's issue
tracker or documentation for:
benchmarks/policy.json ERROR BGV105 /stability/minimumMeasurements: Value must be greater than zero; actual value was 0. ERROR BGV117 /metrics/meanNanoseconds: warningPercent (10) >= failurePercent (10). warningPercent must be strictly less than failurePercent for the policy to be meaningful.
Useful flags on validate:
| Flag | Purpose |
|---|---|
--json <path> |
Write a machine-readable validation report covering every requested artifact |
--quiet |
Suppress console output (report/exit code still work) |
Exit code is 0 if every requested artifact is valid, 12 otherwise —
independent of check's exit codes, since validate answers a different
question (“is this file correct?”) than check does (“do these results
pass the policy?”).
What this is not
- Not a benchmark execution service — BenchmarkDotNet remains the measurement engine; this tool only evaluates its output.
- Not a hosted dashboard or continuous-benchmarking platform. If you want historical trend storage and a web UI out of the box, look at established hosted platforms instead.
Why
Correctness includes performance correctness. A silent regression that nobody reads in a console log is still a regression. BenchmarkGate makes performance a CI-enforced contract — a build that goes red, not a report that might get read.
Status / roadmap
See ROADMAP.md.
License
Apache-2.0. See LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.4.0-alpha.1 | 74 | 8/6/2026 |
| 0.3.0-alpha.1 | 70 | 8/2/2026 |
| 0.2.0-alpha.1 | 68 | 7/28/2026 |
| 0.1.0-alpha.1 | 67 | 7/27/2026 |