OpenChainBench
Tutorial

Submit a benchmark.

Anyone can publish on OpenChainBench. Four steps, no committee, no editorial gatekeeping. The format is fixed, the methodology is yours.

01

Write a spec

One YAML file.

02

Run a harness

Push metrics to Prometheus.

03

Open a PR

The page renders itself.

04

Iterate

Numbers update every minute.

Step 1 — Write the spec

Drop a file at benchmarks/<your-slug>.yml. It is the source of truth for the report — title, abstract, methodology, providers and the PromQL that fills in the numbers.

# benchmarks/wallet-portfolio-latency.yml

slug: wallet-portfolio-latency
number: "005"
title: Wallet Portfolio API — Read Latency
subtitle: How fast each wallet API returns a complete portfolio for a busy address.
category: Wallets
status: live
metric: Portfolio read
unit: ms

abstract: |
  We benchmark how long the major wallet APIs take to return a full
  portfolio (tokens, balances, USD values, NFTs) for a known busy address
  across 12 chains. The harness issues identical GETs from three regions
  and records p50, p90 and p99 wall-clock latency along with success rate.

methodology:
  - "Address set: 200 addresses with 50+ tokens across at least 5 chains."
  - "Cadence: 1 request / address / region every 60 s for 24 hours."
  - "Timeout: 5,000 ms. Failures excluded from latency aggregates."
  - "Regions: us-east-1, eu-west-1, ap-southeast-1."

findings: []  # filled in once you have data and want to publish a take

source: https://github.com/OpenChainBench/OpenChainBench/tree/main/harnesses/wallet-portfolio

prometheus:
  url: https://prom.example.com
  window: 24h

providers:
  - slug: provider-a
    name: Provider A
    tag: v3 endpoints
    secondary: { label: "Chains", value: "44" }
    queries:
      p50: histogram_quantile(0.5,  sum by (le) (rate(ocb_portfolio_ms_bucket{provider="provider-a"}[24h])))
      p90: histogram_quantile(0.9,  sum by (le) (rate(ocb_portfolio_ms_bucket{provider="provider-a"}[24h])))
      p99: histogram_quantile(0.99, sum by (le) (rate(ocb_portfolio_ms_bucket{provider="provider-a"}[24h])))
      success: sum(rate(ocb_portfolio_total{provider="provider-a", success="true"}[24h])) / sum(rate(ocb_portfolio_total{provider="provider-a"}[24h]))
      sample_size: sum(increase(ocb_portfolio_total{provider="provider-a"}[24h]))
      series: histogram_quantile(0.5, sum by (le) (rate(ocb_portfolio_ms_bucket{provider="provider-a"}[1h])))

That is the entire wire format. The Zod schema in src/lib/spec-schema.ts is the single source of truth; pnpm validate lints every spec in CI.

Step 2 — Run the harness

The harness is whatever script measures what you specified. Bun, Node, Python, Go — pick what fits the providers. The contract is small:

  • Run continuously, push to a Prometheus instance reachable over HTTPS.
  • Use the metric and label names referenced by your YAML — they are how the site retrieves your numbers.
  • Document timeouts, regions and inputs in a harnesses/<slug>/README.md so anyone can reproduce.
  • Don't commit API keys. Read them from environment variables.

Step 3 — Dry-run + open the PR

Test the queries locally before opening the PR:

pnpm validate                           # schema lint
pnpm spec:dry-run wallet-portfolio-latency   # hit Prometheus, print resolved numbers
pnpm dev                                # render the page locally

Open the PR. CI runs pnpm validate, pnpm typecheck and the build. Once merged, the site re-queries Prometheus every 60 seconds and your benchmark goes live on the next revalidation.

Step 4 — Iterate

Edit the YAML to add providers, change the window, swap the Prometheus URL, expand to more regions. Each merge to main pushes a new build; ISR picks up changes within the minute.

Reference