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
7 changes: 7 additions & 0 deletions benchmarks/keyed-rpc-robinhood.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ findings:
- "{{name:alchemy}} records {{p50:alchemy}} via its edge infrastructure."
- "{{name:quicknode}} delivers {{p50:quicknode}} via its shared-endpoint fleet."

# Single-vantage bench: the by-region grid and any region-aware surface
# show only the Singapore probe. The us-east series still exists in
# Prometheus (staging exposes it via region tabs) but prod does not
# surface it.
aggregate_filters:
region: sgp

faq:
- q: "Which Robinhood Chain RPC provider is fastest?"
a: "Per the live data above: {{name:chainstack}} at {{p50:chainstack}} p50 (24h). It is the lowest-latency keyed provider for Robinhood Chain in this benchmark."
Expand Down
29 changes: 27 additions & 2 deletions src/components/region-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,40 @@ import { buildProviderColors } from "@/lib/series-colors";

type Props = { benchmark: Benchmark };

const REGIONS = [
const LEGACY_REGIONS = [
{ key: "us-east", label: "US-East" },
{ key: "eu-west", label: "EU-West" },
{ key: "ap-southeast", label: "AP-Southeast" },
] as const;

const REGION_LABELS: Record<string, string> = {
"us-east": "US-East",
"us-west": "US-West",
"eu-west": "EU-West",
"ap-southeast": "AP-Southeast",
sgp: "Singapore",
global: "Global",
};

/** Columns are driven by the live spec, not by whatever regions the
* snapshot happens to carry (prod and staging share worker snapshots,
* so a divergent branch's regions would otherwise leak):
* 1. dimensions.region declared → those columns, in declared order.
* 2. aggregate_filters.region pinned → that single column.
* 3. neither → the legacy fixed three-column layout. */
function regionColumns(b: Benchmark): { key: string; label: string }[] {
const dims = (b.dimensions?.region ?? []).filter((r) => r.value !== "all");
if (dims.length > 0) return dims.map((r) => ({ key: r.value, label: r.label }));
const pinned = b.aggregateFilters?.region;
if (pinned) return [{ key: pinned, label: REGION_LABELS[pinned] ?? pinned }];
return [...LEGACY_REGIONS];
}

export function RegionGrid({ benchmark }: Props) {
const { results, unit, extras } = benchmark;

const REGIONS = useMemo(() => regionColumns(benchmark), [benchmark]);

// Both maps recompute O(n*m) over results × regions. Memoise so the
// grid doesn't reprice every cell on each parent re-render (parent
// re-renders on every chain/region tab change and every chart view
Expand All @@ -32,7 +57,7 @@ export function RegionGrid({ benchmark }: Props) {
map.set(region.key, m);
}
return map;
}, [results, extras.regions]);
}, [results, extras.regions, REGIONS]);

if (!results.length) return null;

Expand Down
19 changes: 16 additions & 3 deletions src/lib/materialize/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export function buildEditorial(
findings: spec.findings,
source: spec.source,
dimensions: spec.dimensions,
aggregateFilters: spec.aggregate_filters,
ledgerColumns: spec.ledger_columns,
providerNotes: spec.provider_notes,
};
Expand All @@ -164,9 +165,21 @@ export async function specToBenchmark(
): Promise<Benchmark> {
const editorial = buildEditorial(spec);

const activeLabels = activeFilterLabels(options);
const isFiltered = Object.keys(activeLabels).length > 0;
const filteredSpec = isFiltered ? applyDimensionsToSpec(spec, activeLabels) : spec;
// Merge spec-declared aggregate defaults UNDER the reader's filters:
// an explicit ?region= / tab selection always wins over the pin. The
// unfiltered-view semantics below (provider augmentation, "All" copy)
// key on the reader's filters only, so a pinned aggregate still reads
// as the bench's headline view rather than a filtered slice.
const merged: BenchmarkFilters = {
...((spec.aggregate_filters ?? {}) as BenchmarkFilters),
...options,
};
const activeLabels = activeFilterLabels(merged);
const isFiltered = Object.keys(activeFilterLabels(options)).length > 0;
const filteredSpec =
Object.keys(activeLabels).length > 0
? applyDimensionsToSpec(spec, activeLabels)
: spec;

const live = await tryLoadLive(filteredSpec, isFiltered);
if (live) {
Expand Down
21 changes: 21 additions & 0 deletions src/lib/spec-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,27 @@ export const SpecSchema = z
})
.optional(),

/**
* Default dimension scope for the unfiltered ("aggregate") build.
* When set, the tier-A snapshot (sig "") is built with these labels
* injected into every query selector, so the bench's headline view,
* TL;DR, JSON-LD and OG all cite the scoped slice instead of an
* average across dimensions. A reader-applied filter (region tab,
* ?region= variant) always wins over these defaults. Presentation
* surfaces (by-region grid) also read it to restrict what a
* single-vantage bench shows.
* First use: keyed-rpc-robinhood pins region=sgp so the default view
* is the Singapore probe. */
aggregate_filters: z
.object({
chain: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/).optional(),
region: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/).optional(),
kind: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/).optional(),
venue: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/).optional(),
})
.strict()
.optional(),

/**
* Optional per-provider chip labels rendered next to the provider
* name in the ranking row. Keys are provider slugs, values are the
Expand Down
3 changes: 3 additions & 0 deletions src/lib/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ export function overlayEditorial(stored: Benchmark, spec: Spec): Benchmark {
// worker running a divergent branch (keyed-rpc-robinhood: main is
// Singapore-only while dev/worker carries the region dims).
dimensions: spec.dimensions,
// Same source-of-truth rule as dimensions: the live YAML decides
// the aggregate pin, never the snapshot.
aggregateFilters: spec.aggregate_filters,
// provider_notes is a YAML editorial declaration: drives the
// per-provider chip rendered next to the name in the ranking row.
// Overlay so newly added notes surface immediately without waiting
Expand Down
9 changes: 9 additions & 0 deletions src/types/benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,15 @@ export type Benchmark = {
kind?: { value: string; label: string }[];
venue?: { value: string; label: string }[];
};
/** Default dimension scope for the unfiltered build (spec
* `aggregate_filters`). Presentation surfaces (e.g. the by-region
* grid) also read it to restrict what a single-vantage bench shows. */
aggregateFilters?: {
chain?: string;
region?: string;
kind?: string;
venue?: string;
};
category: "Aggregators" | "Bridges" | "Blockchains" | "Trading" | "Wallets" | "RPCs" | "NFT APIs" | "Explorers" | "RWA";
results: ProviderResult[];
/** Per-chain leader, computed only on the unfiltered ("All chains") view
Expand Down
Loading