Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
5b57a7e
robinhood chain: chains hub entry, chain-kpis, l2-block-time (HTTP po…
Jul 13, 2026
d6751e7
Merge pull request #1139 from ChainBench/ship/robinhood-main
Flotapponnier Jul 13, 2026
987b0c3
ship solana-rpc to prod: bench 075, harness solana probe path, bump l…
Jul 13, 2026
c03dd8f
Merge pull request #1153 from ChainBench/ship/solana-rpc-prod
Flotapponnier Jul 13, 2026
3991057
sync: cherry-pick citable/stat drift fixes to main (#1155)
Flotapponnier Jul 13, 2026
1b8cf60
sync: cherry-pick /api/compare + openapi coverage to main (#1157)
Flotapponnier Jul 13, 2026
f99e133
sync: cherry-pick Wave 1 P2 batch to main (#1159)
Flotapponnier Jul 13, 2026
2e37138
ship tokenized-stock-peg + tokenized-stock-weekend-drift to prod, bum…
Jul 14, 2026
31c2921
Merge pull request #1162 from ChainBench/ship/tsp-weekend-main
Flotapponnier Jul 14, 2026
05e168b
subsidy is a chain KPI, not a bench: kill standalone spec, add 3 card…
Jul 14, 2026
5c2d4d7
Merge pull request #1164 from ChainBench/ship/subsidy-kpis-main
Flotapponnier Jul 14, 2026
d769303
rwa: new category, tokenized-stock-peg moves in, 11 equity logos + re…
Jul 13, 2026
bbe9140
rwa: complete product pages, hood/qqq/coin/orca/pyth logos + dual-iss…
Jul 13, 2026
44fcb7a
bump lockstep cache keys for RWA category ship
Jul 14, 2026
69abbb3
Merge pull request #1165 from ChainBench/ship/rwa-category-main
Flotapponnier Jul 14, 2026
dec82c7
ship: RWA 077 xstocks-peg + 078 usdy-nav-basis to prod (#1167)
Flotapponnier Jul 14, 2026
8a881c4
usdy: 3-retry on Orca RPC to fix 40% success rate (#1168) (#1169)
Flotapponnier Jul 14, 2026
ee105cb
hyperliquid frontend page: add ProviderLogo in the hero next to the name
Jul 14, 2026
c09a7a4
Merge pull request #1172 from ChainBench/ship/hl-logo-main
Flotapponnier Jul 14, 2026
bcaa7d0
Merge pull request #1166 from ChainBench/feat/predexon-pm-provider
Flotapponnier Jul 14, 2026
abf6005
bump lockstep cache keys for Predexon ship
Jul 14, 2026
ad8a424
Merge pull request #1174 from ChainBench/chore/cherry-predexon-main
Flotapponnier Jul 14, 2026
2078045
add bench 086 polkadot-rpc: first Substrate chain in the RPC cluster …
Flotapponnier Jul 15, 2026
1b8ca78
ship: Polkadot page + Parity product to prod (#1187)
Flotapponnier Jul 15, 2026
ba10be7
hotfix: bump bench-set cache keys — purge poisoned all-benchmarks agg…
Flotapponnier Jul 15, 2026
44291ca
chain-kpis: add polkadot to registry (DOT native, stables via Asset H…
Flotapponnier Jul 16, 2026
6b97091
rpc-capabilities: integrity + consensus probes (unblocks bench 083 on…
Flotapponnier Jul 16, 2026
beaa79f
add bench 087 ws-head-latency-base + 088 ws-head-latency-solana (#119…
Flotapponnier Jul 16, 2026
e5b9be8
ws-head-latency: bring harness + parent bench 081 + region multi-regi…
Flotapponnier Jul 16, 2026
168b3d6
ws-head-latency: align region env var with rpc-capabilities (REGION n…
Flotapponnier Jul 16, 2026
80f4fc6
prom: scrape ws-head-latency-{us,eu,sgp} on Railway (#1202)
Flotapponnier Jul 16, 2026
638c065
rename ws-head-latency -> ws-head-latency-ethereum for sibling slug p…
Flotapponnier Jul 16, 2026
1d7996a
network-coverage: drop coinstats (free tier credits exhausted) (#1206…
Flotapponnier Jul 16, 2026
c3f76f1
Revert "network-coverage: drop coinstats (free tier credits exhausted…
Flotapponnier Jul 16, 2026
292a0fc
tsp-arb-latency: lower trigger 50 -> 25 bps + credit sub-poll closure…
Flotapponnier Jul 16, 2026
415483a
drop bench 084 indexer-latency (harness pruned, spec deleted) (#1218)…
Flotapponnier Jul 16, 2026
aeaef30
video/render: strict Zod body schema before upstream forward (#1217)
Flotapponnier Jul 16, 2026
1f13d46
seo: 200 placeholders + sitemap threshold buffer (#1223)
Flotapponnier Jul 16, 2026
da032f9
ws-head-latency: sub-ms histogram floor + keyed slots for base/solana…
Flotapponnier Jul 16, 2026
800d81a
ship: ungate bench 085 evm-block-builders on prod (#1227) (#1228)
Flotapponnier Jul 16, 2026
5489f4a
tsp-arb-latency: drop 5 illiquid tickers (TSLA GOOGL AMZN MSFT SPY) (…
Flotapponnier Jul 16, 2026
ba97dc5
perp-fees harness: fix Paradex depth-skip, gains SOL slot, dYdX walk …
Flotapponnier Jul 16, 2026
c3bb950
batch 2: MEV chips + rpc copy + Aster/edgeX + Cardano/Sui/Cosmos/Avax…
Flotapponnier Jul 16, 2026
0f4458c
rpc-capabilities: add 4 keyless providers (ThirdWeb Blast Gateway.fm …
Flotapponnier Jul 16, 2026
5040bcb
fix(bench): sample-size PromQL + leader reliability floor (#1175) (#1…
Flotapponnier Jul 16, 2026
ce2e22e
ws-head-latency: add Onfinality Ethereum to keyless cohort (#1241) (#…
Flotapponnier Jul 16, 2026
23d8c42
ship: add 080 + 083 spec files to main + ungate + fix 085 file-missin…
Flotapponnier Jul 16, 2026
e23b22f
drop oracle-freshness (082) spec + sync REMOVED with main state (#124…
Flotapponnier Jul 16, 2026
bcd75fc
perp-fees + validator-yield: declare new providers in specs (#1247)
Flotapponnier Jul 16, 2026
069d062
cherry-pick: aggregator-head-lag downtime pills → main (#1248)
Flotapponnier Jul 16, 2026
1bb3b93
drop bench 080 tokenized-stock-arb-latency (Rob Chain pools too illiq…
Flotapponnier Jul 16, 2026
f4cbb1c
cherry-pick: SEO/E-E-A-T pack → main (#1256)
Flotapponnier Jul 17, 2026
62f930e
ticker: defensive ceiling on live-number values (#1258)
Flotapponnier Jul 17, 2026
a8df110
ticker: also skip seeding display + reset it when value exceeds ceili…
Flotapponnier Jul 17, 2026
474653e
products: skip degraded-read tripwire when every appearance is unresp…
Flotapponnier Jul 17, 2026
d994400
chains: register cosmos-hub so sitemap emits /chains/ instead of /pro…
Flotapponnier Jul 17, 2026
d3d54ba
products: tripwire fires only when every appearance claims live (clou…
Flotapponnier Jul 17, 2026
77a6fb9
docs(bridge-monitor): reflect OCB VPS deployment (was still pointing …
Flotapponnier Jul 17, 2026
4dd4b98
hotfix: bump bench-set + all-benchmarks cache keys (v36/v39) — purge …
Flotapponnier Jul 18, 2026
337f94d
spec: unstable_noStore() when returning draft placeholders (kills poi…
Flotapponnier Jul 18, 2026
427c684
spec: throttle aggregate Redis fan-out to 12 concurrent (was 68, caus…
Flotapponnier Jul 18, 2026
06b6c64
rpc-capabilities: drop thirdweb from 8 chains (Railway IPs rate-limit…
Flotapponnier Jul 18, 2026
d88ecd1
hotfix: bump cache keys v37/v40 — purge poisoned 15-bench draft set (…
Flotapponnier Jul 18, 2026
cb50792
hotfix: GSC Dataset warnings (cherry-pick from dev) (#1301)
Flotapponnier Jul 18, 2026
07dd175
consolidate solana-official + solana-labs into 'solana' provider (#12…
Flotapponnier Jul 18, 2026
0e58569
hotfix: bump cache keys v38/v41 — purge poisoned aggregate showing aw…
Flotapponnier Jul 18, 2026
489fbed
cherry-pick: revalidate-aggregate route → main (worker POST hook) (#1…
Flotapponnier Jul 18, 2026
e826045
Revert "hotfix: bump cache keys v38/v41 — purge poisoned aggregate sh…
Flotapponnier Jul 18, 2026
f486bca
Phase 2 aggregate reader: fast path via CDN blob → falls back to Redi…
Flotapponnier Jul 18, 2026
5d33e45
solana: display name 'Solana' (not 'Solana Labs' / 'Solana Foundation…
Flotapponnier Jul 19, 2026
398053c
Phase 3 site side: per-bench + per-variant reads via CDN blobs (kills…
Flotapponnier Jul 19, 2026
3788aaf
cherry-pick: drop mobula from PM benches (they stopped serving) (#1312)
Flotapponnier Jul 20, 2026
dc12a39
drop mobula from PM freshness answer page (they stopped serving) (#1313)
Flotapponnier Jul 20, 2026
6e75a81
Phase 3.5: kill remaining SRH callers (/api/series, search-featured, …
Flotapponnier Jul 20, 2026
9fd6d2a
tsp-weekend-drift: narrative reflect current data (MU/AMD/PLTR widest…
Flotapponnier Jul 22, 2026
53071f7
share-card leaderboard: dense scaling (matches renderRanking pattern)…
Flotapponnier Jul 22, 2026
16a3b7c
tsp-weekend-drift: add sample_size query (fixes '0 samples' display) …
Flotapponnier Jul 22, 2026
dff5653
add sample_size query to 5 specs (fixes '0 samples' display on share …
Flotapponnier Jul 22, 2026
bf80dbd
share-card snapshot: fix title/subtitle overlap on wrapping text (sat…
Flotapponnier Jul 22, 2026
d325398
perp-execution-quality: switch $BOT headline size $10k→$5k (HIP-3 boo…
Flotapponnier Jul 22, 2026
0760068
home-bench-table: use ProviderLogo instead of first-letter chips (kil…
Flotapponnier Jul 22, 2026
432d5ec
Phase 1 aggregate broadcast (VPS-served): worker writes /state/aggreg…
Flotapponnier Jul 22, 2026
0a99bee
Phase 3 worker: extend publish-aggregate with per-bench + per-variant…
Flotapponnier Jul 22, 2026
d47359b
bench 090 token-trade-coverage: spec YAML + Go harness (Mobula/Bitque…
Flotapponnier Jul 23, 2026
4ec71b0
chore: remove accidentally-committed scanner binary + add .gitignore …
Flotapponnier Jul 23, 2026
642af18
bitquery: use Authorization Bearer (ory_at_ keys reject X-API-KEY) + …
Flotapponnier Jul 23, 2026
8bcdea9
token-trade-coverage: fix Mobula params/fields (blockchain, tokenAddr…
Flotapponnier Jul 23, 2026
b5f2a78
codex: drop invalid exchangeAddress field (not on Event type); use ev…
Flotapponnier Jul 23, 2026
0dd1cc8
token-trade-coverage: refresh reference tokens (BONK/WIF/PEPE/MOG/CAK…
Flotapponnier Jul 23, 2026
6fe50db
hotfix: token-trade-coverage back to status=draft (needs 24h Prom dat…
Flotapponnier Jul 23, 2026
7f79265
chore: re-trigger prod-deploy (worker aggregate blob now includes tok…
Flotapponnier Jul 23, 2026
69edc1c
add osmosis-rpc bench (091) + register Osmosis chain — first Cosmos S…
Flotapponnier Jul 23, 2026
e7ccf63
token-trade-coverage: quota-respecting sub-sampling (Bitquery 6x spar…
Flotapponnier Jul 23, 2026
341d82d
hotfix(osmosis-rpc): split methodology[7] entry (>500 chars Zod cap) …
Flotapponnier Jul 23, 2026
f2c72dd
add benches 092 hyperliquid-rpc + 093 tron-rpc (#1341) (#1342)
Flotapponnier Jul 24, 2026
5886294
add stakely SVG logo (bench 092 hyperliquid-rpc provider) (#1344) (#1…
Flotapponnier Jul 24, 2026
2585650
add hypurrscan + purroofgroup logos (bench 092 providers) (#1346) (#1…
Flotapponnier Jul 24, 2026
d92c3d3
add 7 RPC benches: cosmos-hub (094) + injective (095) + neutron (096)…
Flotapponnier Jul 24, 2026
70ccd9c
add polkachu + lavenderfive + imperator SVG logos (Cosmos RPC provide…
Flotapponnier Jul 24, 2026
3d00979
add thirdweb logo + rename World Chain (Alchemy) -> World Chain (#135…
Flotapponnier Jul 24, 2026
06b979e
hotfix(products): add thirdweb registry entry (fixes /products/thirdw…
Flotapponnier Jul 24, 2026
d7cb3ce
hotfix(products): relax tripwire for newly-added providers (unblock p…
Flotapponnier Jul 24, 2026
470625b
hotfix: drop thirdweb from 4 new benches to unblock prod deploys (#13…
Flotapponnier Jul 24, 2026
9bdc836
cherry-pick: rwa-yield-accuracy bench 089 (Sprints 1-4) to main
Jul 24, 2026
2b72c8e
Merge pull request #1363 from ChainBench/cherry/rwa-yield-sprint4-mai…
Flotapponnier Jul 24, 2026
d687cea
hotfix: bump rpc-hub-cohort cache v4->v5 (bust sticky-null on chain R…
Flotapponnier Jul 24, 2026
4ed7e9a
Merge pull request #1366 from ChainBench/feat/rwa-yield-add-syrupusdc
Flotapponnier Jul 24, 2026
b01d5ad
Merge pull request #1367 from ChainBench/cherry/rwa-yield-syrupusdc-main
Flotapponnier Jul 24, 2026
332e971
Merge pull request #1369 from ChainBench/feat/rwa-yield-usdy-oracle-fix
Flotapponnier Jul 24, 2026
4a1e806
cherry-pick: Gelato / QuickNode rename to main (#1371)
Flotapponnier Jul 24, 2026
028c0ed
Merge pull request #1370 from ChainBench/cherry/rwa-yield-usdy-fix-main
Flotapponnier Jul 24, 2026
c94bab7
Merge pull request #1372 from ChainBench/feat/rwa-yield-logos-registr…
Flotapponnier Jul 24, 2026
1642b40
Merge pull request #1373 from ChainBench/cherry/rwa-yield-logos-main
Flotapponnier Jul 24, 2026
94a61b3
ci: auto-sync dev from main after every prod merge (#1375)
Flotapponnier Jul 24, 2026
d3a6969
cherry-pick: token-trade-coverage flip status draft -> live
Jul 24, 2026
daab2a7
Merge pull request #1380 from ChainBench/cherry/ttc-live-main-v2
Flotapponnier Jul 24, 2026
485d723
add bench 101 wormhole-vaa-latency (Wormhole VAA finalization by sour…
Flotapponnier Jul 24, 2026
d8e3ac3
sync: main → dev (resolve 16 conflicts)
Jul 24, 2026
6285878
chart index: drop showDowntime prop (removed in dev's chart.tsx via #…
Jul 24, 2026
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
109 changes: 109 additions & 0 deletions .github/workflows/sync-dev-from-main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
name: Sync dev from main

# Purpose
# -------
# The workflow enforces the AGENTS.md rule "immediately fast-forward dev
# from main after a hotfix". Every hotfix that lands on main used to
# require a manual `git checkout dev && git merge --ff-only main && git
# push` step; that step was skipped often enough for dev to drift 100+
# commits behind main, silently rotting the staging environment.
#
# On every push to main this job:
# 1. Tries a fast-forward of dev to main. If it succeeds, dev is now
# identical to main and the staging deploy fires as usual (its
# workflow triggers on push to dev).
# 2. If a fast-forward isn't possible (dev has commits main doesn't),
# the job attempts a real merge commit. Clean auto-merge = pushed
# straight to dev.
# 3. Only when git itself can't resolve the merge (real conflicts) do
# we fall back to opening a "sync/main-to-dev-<sha>" branch + a PR
# against dev. A human resolves those conflicts by merging the PR.
#
# The job is intentionally lenient: pushing to dev directly is normally
# forbidden (AGENTS.md), but this bot is the one exception because it
# only carries commits that main has already accepted.

on:
push:
branches:
- main
workflow_dispatch:

concurrency:
group: sync-dev-from-main
cancel-in-progress: false

jobs:
sync:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout full history
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: dev

- name: Configure bot identity
run: |
git config user.name "ocb-sync-bot"
git config user.email "ocb-sync-bot@users.noreply.github.com"

- name: Try fast-forward dev → main
id: ff
run: |
set -e
git fetch origin main:refs/remotes/origin/main
if git merge-base --is-ancestor origin/main HEAD; then
echo "already-in-sync=true" >> "$GITHUB_OUTPUT"
echo "dev already contains origin/main; nothing to do."
exit 0
fi
if git merge --ff-only origin/main; then
git push origin dev
echo "ff-succeeded=true" >> "$GITHUB_OUTPUT"
echo "dev fast-forwarded to $(git rev-parse --short HEAD)"
exit 0
fi
echo "ff-failed=true" >> "$GITHUB_OUTPUT"

- name: Attempt clean merge commit
if: steps.ff.outputs.ff-failed == 'true'
id: merge
run: |
set -e
if git merge --no-edit --no-ff origin/main -m "sync: main → dev (auto-merge $(git rev-parse --short origin/main))"; then
git push origin dev
echo "merge-pushed=true" >> "$GITHUB_OUTPUT"
echo "dev auto-merged main at $(git rev-parse --short HEAD)"
exit 0
fi
git merge --abort
echo "merge-failed=true" >> "$GITHUB_OUTPUT"

- name: Open sync PR on conflict
if: steps.merge.outputs.merge-failed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -e
SHORT=$(git rev-parse --short origin/main)
BRANCH="sync/main-to-dev-$SHORT"
git checkout -B "$BRANCH"
# Force a merge commit that stops on conflicts. We DO NOT
# push conflict markers to dev; instead we push a branch that
# a human can pull, resolve locally, and merge into dev.
git reset --hard dev
git merge --no-edit --no-ff origin/main || true
git add -A
git commit -m "sync: main → dev (CONFLICTS — resolve before merge)" || true
git push -f origin "$BRANCH"
gh pr create \
--repo "$GITHUB_REPOSITORY" \
--base dev \
--head "$BRANCH" \
--title "sync: main → dev (auto, needs conflict resolution)" \
--body "Automated by \`.github/workflows/sync-dev-from-main.yml\`. Fast-forward + auto-merge both failed; a human needs to resolve conflicts and merge this PR into \`dev\`. Base main SHA: $SHORT." \
|| echo "PR already exists for $BRANCH; leaving it alone."
12 changes: 5 additions & 7 deletions answers/which-prediction-market-data-api-is-the-freshest.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
slug: which-prediction-market-data-api-is-the-freshest
question: "Which prediction market data API publishes the freshest Polymarket data?"
short_answer: |
{{best_name}} currently relays Polymarket trades the fastest at {{best_p50}} (p50, 24h) versus Polymarket's own CLOB WebSocket gateway, measured by cross correlating trade events on Polymarket, Mobula and Codex on the same rotating basket of top 20 markets by 24 hour volume.
{{best_name}} currently relays Polymarket trades the fastest at {{best_p50}} (p50, 24h) versus Polymarket's own CLOB WebSocket gateway, measured by cross correlating trade events on Polymarket and Codex on the same rotating basket of top 20 markets by 24 hour volume.

benchmark: pm-data-freshness

intro: |
Prediction markets produce the most time sensitive event stream in crypto. An election market settles in seconds, a sports book moves on every play, and the price tick a trading UI shows is only as fresh as the API behind it. Builders integrating Polymarket through a data provider rather than hitting the CLOB directly need to know how many milliseconds that provider adds between Polymarket publishing a trade and the provider relaying the same trade to its WebSocket subscribers. This page answers exactly that. The OpenChainBench pm-data-freshness harness holds three WebSocket subscribers in parallel: Polymarket's own CLOB gateway (the canonical T0), Mobula's PM WebSocket, and Codex GraphQL subscriptions, all subscribed to the same basket of top 20 Polymarket markets by 24 h volume, refreshed every 5 minutes. Each trade is matched across providers by a tuple of conditionId, price rounded to 3 decimals, trade size and a 5 second time bucket; the per provider lag versus Polymarket's gateway publish time is recorded as a Prometheus histogram and the leaderboard ranks by p50 in milliseconds, lower is fresher.
Prediction markets produce the most time sensitive event stream in crypto. An election market settles in seconds, a sports book moves on every play, and the price tick a trading UI shows is only as fresh as the API behind it. Builders integrating Polymarket through a data provider rather than hitting the CLOB directly need to know how many milliseconds that provider adds between Polymarket publishing a trade and the provider relaying the same trade to its WebSocket subscribers. This page answers exactly that. The OpenChainBench pm-data-freshness harness holds two WebSocket subscribers in parallel: Polymarket's own CLOB gateway (the canonical T0) and Codex GraphQL subscriptions, both subscribed to the same basket of top 20 Polymarket markets by 24 h volume, refreshed every 5 minutes. Each trade is matched across providers by a tuple of conditionId, price rounded to 3 decimals, trade size and a 5 second time bucket; the per provider lag versus Polymarket's gateway publish time is recorded as a Prometheus histogram and the leaderboard ranks by p50 in milliseconds, lower is fresher.

methodology: |
Three WebSocket clients run in parallel inside the harness on a Railway europe west 4 instance. Polymarket's own gateway (`wss://ws-subscriptions-clob.polymarket.com/ws/market`, public, no auth, sub 50 ms publish latency from EU West) is the canonical T0 by construction because nothing downstream can be faster than the source. Mobula's PM WebSocket (`wss://pm-api-prod-eu.mobula.io`) requires an API key in the subscribe payload and a browser User Agent on the upgrade request (Cloudflare on the gateway silently filters the default Go HTTP UA). Codex GraphQL (`wss://graph.codex.io/graphql` with the `graphql-transport-ws` subprotocol) runs an `onPredictionTradesCreated` firehose subscription filtered client side to the Polymarket protocol marketIds in the active basket. The cross correlation key is `(conditionId, priceUSD times 1000 rounded, sizeUSD times 1 million rounded, floor(trade_time / 5s))`; the 5 second bucket absorbs minor clock skew between gateways without merging unrelated trades. Histogram buckets run 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 30000, 60000 ms. Providers that fail to relay a matched trade within 90 seconds are not counted toward p50, only toward their receive total, so a provider cannot look fresh on the leaderboard by silently dropping events; the success rate column surfaces that.
Two WebSocket clients run in parallel inside the harness on a Railway europe west 4 instance. Polymarket's own gateway (`wss://ws-subscriptions-clob.polymarket.com/ws/market`, public, no auth, sub 50 ms publish latency from EU West) is the canonical T0 by construction because nothing downstream can be faster than the source. Codex GraphQL (`wss://graph.codex.io/graphql` with the `graphql-transport-ws` subprotocol) runs an `onPredictionTradesCreated` firehose subscription filtered client side to the Polymarket protocol marketIds in the active basket. The cross correlation key is `(conditionId, priceUSD times 1000 rounded, sizeUSD times 1 million rounded, floor(trade_time / 5s))`; the 5 second bucket absorbs minor clock skew between gateways without merging unrelated trades. Histogram buckets run 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 30000, 60000 ms. Providers that fail to relay a matched trade within 90 seconds are not counted toward p50, only toward their receive total, so a provider cannot look fresh on the leaderboard by silently dropping events; the success rate column surfaces that.

limitations:
- "Polymarket's own gateway is the canonical T0 by construction. Its row on the leaderboard sits near zero because the harness compares everything else against it, not because Polymarket has solved network latency; the displayed sub millisecond value is a floor (vector(0.5)) so the row stays visible on the linear chart axis next to the multi second Codex value."
Expand All @@ -20,11 +20,9 @@ limitations:

faq:
- q: "Which Polymarket data API has the lowest latency right now?"
a: "{{best_name}} currently leads at {{best_p50}} (p50 over the last 24 hours), measured as wall clock time from Polymarket's own CLOB WebSocket publish to provider relay on the same trade. The leaderboard re sorts every minute on fresh Prometheus samples, so the answer reflects the actual measured lag on the active market basket, not a marketing claim. Mobula's edge cached relay typically clocks tens of milliseconds; Codex's on chain Polygon indexer carries a structural floor near 2 seconds because it ingests block confirmations."
a: "{{best_name}} currently leads at {{best_p50}} (p50 over the last 24 hours), measured as wall clock time from Polymarket's own CLOB WebSocket publish to provider relay on the same trade. The leaderboard re sorts every minute on fresh Prometheus samples, so the answer reflects the actual measured lag on the active market basket, not a marketing claim. Codex's on chain Polygon indexer carries a structural floor near 2 seconds because it ingests block confirmations."
- q: "What does freshness delta mean for a prediction market API?"
a: "The bench connects to Polymarket's own CLOB WebSocket and to each provider's WebSocket simultaneously, subscribes to the same markets, and for every trade event records how many milliseconds the provider takes to relay the event after Polymarket itself publishes it. Lower is better. Polymarket's own gateway publish time is the canonical T0 because by construction nothing downstream can be faster than the source. The cross correlation key (conditionId, price, size, 5 s bucket) survives minor clock skew between gateways without merging unrelated trades."
- q: "Is Mobula's PM WebSocket faster than Codex?"
a: "Yes, by a structural margin, because the two providers do fundamentally different things under the hood. Mobula's PM WebSocket is an edge cached relay of Polymarket's own gateway, so its p50 delta is roughly the network round trip between the two gateways plus a few milliseconds of bookkeeping. Codex ingests the on chain Polygon confirmation of each trade, which adds Polygon block time (around 2 seconds) before any trade can be relayed. For a live UI, Mobula's path wins on freshness; for on chain reconciliation or settlement workflows, Codex's chain indexed path is what you actually want. The leaderboard surfaces both numbers honestly."
- q: "Why not include Polymarket REST polling on this bench?"
a: "Freshness is a WebSocket question. REST polling at 1 second cadence would have a floor freshness near 500 ms (poll interval divided by 2) plus round trip time, dominated by how often you poll. The Polymarket gateway WebSocket exists for exactly this reason, to avoid that floor. Adding REST as a row would make the leaderboard noisy without changing the conclusion: WebSocket beats polling by definition for real time data."
- q: "Are these numbers comparable to Kalshi or Limitless?"
Expand All @@ -40,5 +38,5 @@ related:
- which-crypto-price-api-is-the-fastest

seo_title: "Which prediction market data API is the freshest in 2026?"
seo_description: "{{best_name}} leads at {{best_p50}} (p50, 24h) versus Polymarket's CLOB gateway, with Mobula and Codex measured live by OpenChainBench on the top 20 Polymarket markets by volume."
seo_description: "{{best_name}} leads at {{best_p50}} (p50, 24h) versus Polymarket's CLOB gateway, with Codex measured live by OpenChainBench on the top 20 Polymarket markets by volume."
status: live
Loading
Loading