Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions benchmarks/arbitrum-rpc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,30 @@ providers:
p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="arbitrum-official", chain="arbitrum", region="sgp"})
series: avg_over_time(rpc_latency_milliseconds{provider="arbitrum-official", chain="arbitrum", region="sgp"}[1h])

- slug: blockvectra
name: BlockVectra
endpoint: https://api.blockvectra.com/v1/arb_mainnet/public
tag: BlockVectra keyless public Arbitrum One endpoint (3 req/s per IP, 1,000-block history window)
formula: "50th percentile over 24h of client-side round-trip latency (ms) for a single `eth_getBlockByNumber(\"latest\", false)` POST sent every 60s from 3 regions (us-east + eu-west + sgp) to BlockVectra's no-key Arbitrum One endpoint."
queries:
p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="blockvectra", chain="arbitrum"})
p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="blockvectra", chain="arbitrum"})
p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="blockvectra", chain="arbitrum"})
mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="blockvectra", chain="arbitrum"})
success: sum(ocb:rpc_call:ok_rate_24h{provider="blockvectra", chain="arbitrum"}) / sum(ocb:rpc_call:rate_24h{provider="blockvectra", chain="arbitrum"})
sample_size: sum(ocb:rpc_call:increase_24h{provider="blockvectra", chain="arbitrum"})
series: avg(avg_over_time(rpc_latency_milliseconds{provider="blockvectra", chain="arbitrum"}[1h]))
regions:
- region: us-east
p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="blockvectra", chain="arbitrum", region="us-east"})
series: avg_over_time(rpc_latency_milliseconds{provider="blockvectra", chain="arbitrum", region="us-east"}[1h])
- region: eu-west
p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="blockvectra", chain="arbitrum", region="eu-west"})
series: avg_over_time(rpc_latency_milliseconds{provider="blockvectra", chain="arbitrum", region="eu-west"}[1h])
- region: ap-southeast
p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="blockvectra", chain="arbitrum", region="sgp"})
series: avg_over_time(rpc_latency_milliseconds{provider="blockvectra", chain="arbitrum", region="sgp"}[1h])

# API-key cohort (tier: keyed). Queries pin tier="keyed", the label the
# rpc-keyed-latency harness emits; the public rows above carry no tier label.
- slug: alchemy
Expand Down
24 changes: 24 additions & 0 deletions benchmarks/ethereum-rpc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,30 @@ providers:
p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="meowrpc", chain="ethereum", region="sgp"})
series: avg_over_time(rpc_latency_milliseconds{provider="meowrpc", chain="ethereum", region="sgp"}[1h])

- slug: blockvectra
name: BlockVectra
endpoint: https://api.blockvectra.com/v1/eth_mainnet/public
tag: BlockVectra keyless public Ethereum endpoint (3 req/s per IP, 1,000-block history window)
formula: "50th percentile over 24h of client-side round-trip latency (ms) for a single `eth_getBlockByNumber(\"latest\", false)` POST sent every 60s from 3 regions (us-east + eu-west + sgp) to BlockVectra's no-key Ethereum endpoint."
queries:
p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="blockvectra", chain="ethereum"})
p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="blockvectra", chain="ethereum"})
p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="blockvectra", chain="ethereum"})
mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="blockvectra", chain="ethereum"})
success: sum(ocb:rpc_call:ok_rate_24h{provider="blockvectra", chain="ethereum"}) / sum(ocb:rpc_call:rate_24h{provider="blockvectra", chain="ethereum"})
sample_size: sum(ocb:rpc_call:increase_24h{provider="blockvectra", chain="ethereum"})
series: avg(avg_over_time(rpc_latency_milliseconds{provider="blockvectra", chain="ethereum"}[1h]))
regions:
- region: us-east
p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="blockvectra", chain="ethereum", region="us-east"})
series: avg_over_time(rpc_latency_milliseconds{provider="blockvectra", chain="ethereum", region="us-east"}[1h])
- region: eu-west
p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="blockvectra", chain="ethereum", region="eu-west"})
series: avg_over_time(rpc_latency_milliseconds{provider="blockvectra", chain="ethereum", region="eu-west"}[1h])
- region: ap-southeast
p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="blockvectra", chain="ethereum", region="sgp"})
series: avg_over_time(rpc_latency_milliseconds{provider="blockvectra", chain="ethereum", region="sgp"}[1h])

# API-key cohort (tier: keyed). Queries pin tier="keyed", the label the
# rpc-keyed-latency harness emits; the public rows above carry no tier label.
- slug: alchemy
Expand Down
2 changes: 2 additions & 0 deletions harnesses/rpc-capabilities/cmd/script/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ func chains() []Chain {
{Slug: "nodies", Name: "Nodies (POKT)", URL: envDefault("RPC_URL_ETHEREUM_NODIES", "https://eth-pokt.nodies.app")},
{Slug: "bloxroute", Name: "bloXroute", URL: envDefault("RPC_URL_ETHEREUM_BLOXROUTE", "https://eth.rpc.blxrbdn.com")},
{Slug: "nownodes", Name: "NOWNodes", URL: envDefault("RPC_URL_ETHEREUM_NOWNODES", "https://public-eth.nownodes.io")},
{Slug: "blockvectra", Name: "BlockVectra", URL: envDefault("RPC_URL_ETHEREUM_BLOCKVECTRA", "https://api.blockvectra.com/v1/eth_mainnet/public")},
},
},
// ─── Polygon PoS (3 providers) ──────────────────────────────
Expand Down Expand Up @@ -331,6 +332,7 @@ func chains() []Chain {
{Slug: "tenderly", Name: "Tenderly Gateway", URL: envDefault("RPC_URL_ARBITRUM_TENDERLY", "https://gateway.tenderly.co/public/arbitrum")},
{Slug: "nodies", Name: "Nodies (POKT)", URL: envDefault("RPC_URL_ARBITRUM_NODIES", "https://arb-pokt.nodies.app")},
{Slug: "arbitrum-official", Name: "Arbitrum Official", URL: envDefault("RPC_URL_ARBITRUM_OFFICIAL", "https://arb1.arbitrum.io/rpc")},
{Slug: "blockvectra", Name: "BlockVectra", URL: envDefault("RPC_URL_ARBITRUM_BLOCKVECTRA", "https://api.blockvectra.com/v1/arb_mainnet/public")},
},
},
// ─── Optimism (6 providers) ─────────────────────────────────
Expand Down
4 changes: 3 additions & 1 deletion src/lib/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,9 @@ const buildProvidersCached = unstable_cache(
// bench-unfiltered-v184.
// v61: thirteen chain RPC pages retire, so every provider on them loses
// that appearance. Lockstep with bench-unfiltered-v187.
["providers-v61"],
// v62: BlockVectra gains two appearances, ethereum-rpc and arbitrum-rpc.
// Lockstep with bench-unfiltered-v189.
["providers-v62"],
// 900 s: the provider index feeds products / compare / answers, whose
// numbers move slowly, and this revalidate is also the effective ISR
// period of those ~500 pages (Next takes the min across a route's caches).
Expand Down
6 changes: 5 additions & 1 deletion src/lib/spec-provider-set.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ describe("the provider set behind the cache keys", () => {
const hash = createHash("sha256").update(sets.join("\n")).digest("hex").slice(0, 16);
const count = sets.reduce((n, s) => n + s.split(":")[1].split(",").length, 0);

// An ADDITION on 2026-11-07: BlockVectra joins the public cohorts on
// ethereum-rpc and arbitrum-rpc (issue #3573). A provider already on
// the site, two more appearances: v189/v182/v107 and providers-v62.
//
// A REMOVAL on 2026-11-06: thirteen chain RPC pages retire (celo,
// taiko, kaia, bob, bitlayer, gravity, axelar, hedera, litecoin,
// soneium, zircuit, merlin, comdex), every row on them with them. No
Expand Down Expand Up @@ -181,6 +185,6 @@ describe("the provider set behind the cache keys", () => {
"Then set EXPECTED to the hash in this failure, and add the provider",
`to PRODUCT_NAMES if it needs a display name. Providers now: ${count}.`,
].join("\n"),
).toBe("35fc07b8e50a5ad2");
).toBe("e0e5b0e42ccb7ee7");
});
});
14 changes: 11 additions & 3 deletions src/lib/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,11 @@ const loadBenchmarkUnfilteredCached = unstable_cache(
// each, and route into the cohort at 60% and 30%. Trnch has the
// lowest baseline, 78.1%, and the second highest trap rate at 90%,
// the only row whose score sits above its own coverage.
["bench-unfiltered-v188", process.env.VERCEL_ENV === "production" ? "prod" : "all"],
// v189: BlockVectra joins the public cohorts on ethereum-rpc and
// arbitrum-rpc (issue #3573), one more public row on each. Cached
// entries hold the old provider set. Moves with all-benchmarks-v182,
// bench-filters-v107 and providers-v62.
["bench-unfiltered-v189", process.env.VERCEL_ENV === "production" ? "prod" : "all"],
{ revalidate: 300, tags: ["benchmarks"] },
);

Expand Down Expand Up @@ -1345,7 +1349,9 @@ const loadAllBenchmarksCached = unstable_cache(
// v180: lockstep with bench-unfiltered-v187 (thirteen chain RPC pages
// retired 2026-11-06; a cached catalog would keep linking them).
// v181: lockstep with bench-unfiltered-v188 (bench 313 coverage column).
["all-benchmarks-v181", process.env.VERCEL_ENV === "production" ? "prod" : "all"],
// v182: lockstep with bench-unfiltered-v189 (BlockVectra on Ethereum and
// Arbitrum).
["all-benchmarks-v182", process.env.VERCEL_ENV === "production" ? "prod" : "all"],
{ revalidate: 300, tags: ["benchmarks"] },
);
export const loadAllBenchmarks = cache(loadAllBenchmarksCached);
Expand Down Expand Up @@ -1601,7 +1607,9 @@ const loadBenchmarkFiltered = unstable_cache(
// retired, each with region and tier tabs).
// v106: lockstep with bench-unfiltered-v188. The coverage panel is
// written under both row slugs, so each tier tab carries it.
["bench-filters-v106", process.env.VERCEL_ENV === "production" ? "prod" : "all"],
// v107: lockstep with bench-unfiltered-v189. The new public rows carry
// region tabs.
["bench-filters-v107", process.env.VERCEL_ENV === "production" ? "prod" : "all"],
{ revalidate: 300, tags: ["benchmarks"] }
);

Expand Down
Loading