AggregatorsUpdated

Fastest crypto price API, live head lag across 6 data providers

Wall-clock head lag in seconds from on-chain swap event to API emission, measured live for Mobula, Codex, GeckoTerminal, Serialized, OKX and Birdeye on Base, BNB Chain, Solana and Robinhood Chain. OKX and Birdeye are measured on Base, BNB Chain and Solana, the three chains where the headline does not read their own timestamps; neither indexes Robinhood Chain.

TL;DR. As of , Codex posts the lowest head lag at 0.05 s (p50, 24h) across 6 ranked providers. Source: OpenChainBench, https://openchainbench.com/benchmarks/aggregator-head-lag.

This benchmark measures the question every builder of a trading UI, a PnL tracker or a live DEX dashboard has to answer before picking a data provider. how many seconds elapse between a swap landing on chain and the same event appearing on the provider's feed. Marketing pages quote "real-time" without a number; this page quotes the number. Mobula's WebSocket, Codex's GraphQL feed, GeckoTerminal's REST endpoint and Serialized's WebSocket trades stream are watched from three regions (us-east, eu-west, sgp). On Base the zero point is a log subscription on the sequencer node, which we hold ourselves; on BNB Chain, Solana and Robinhood Chain it is the on-chain timestamp against canonical-tip archive nodes. Because each chain has its own base block cadence (Base's 200 ms blocks, Solana's ~400 ms slots, BNB's sub-second to 3 s blocks), the headline winner shifts by chain. On Solana the leader is Codex at <0.01 s; on Base it's Codex at 0.05 s; on BNB Chain it's Serialized at 0.02 s. p50 and p99 are computed via Prometheus `quantile_over_time` over a 24-hour window so the leaderboard reflects sustained freshness, not a cherry-picked cold-start sample. The same harness tracks presence (2,880 expected samples per provider per day), so a provider whose feed dropped for an hour shows it on the success rate column rather than disappearing silently from the latency aggregate.

Methodology

We measure the gap between a transaction settling on chain and the same transaction appearing on each aggregator's data feed. The harness watches reference pools across Base, BNB Chain, Solana and Robinhood Chain from three regions (us-east, eu-west, sgp), records every new on-chain event with millisecond timestamps, and observes when each aggregator's WebSocket reflects the same event.

  • Aggregators measured: Mobula, Codex, GeckoTerminal and Serialized on all four chains; OKX and Birdeye on Base, BNB and Solana. Neither can scope a subscription to a pool, so both are subscribed per token and matched to the bench pool by transaction hash, their off-pool trades discarded rather than scored. Both send whole-second timestamps, which is why they are measured only on chains whose headline reads a clock we hold rather than the provider's own.
  • Robinhood Chain carries four of the six feeds. Neither OKX nor Birdeye indexes it, measured rather than inferred: both accept the subscription and then deliver nothing (0 trades in 40 to 45 s, on the pool and on its non-stable leg) while Base and BNB on the same code delivered hundreds. An accepted subscription is not evidence of coverage on either feed.
  • Chains: Base, BNB Chain, Solana, Robinhood Chain.
  • Reference on BNB Chain: a node subscription we hold ourselves, every emission matched to it by transaction hash, the ruler Base uses. Until 2026-10-03 the column used each provider's own timestamp, assuming BNB's chain-supplied timestamps sat within roughly 60 ms of a trade becoming observable. Measured, that gap is 569 ms, so the old column tracked block time more than any pipeline: the four feeds sat within 9% of each other, against the common clock they spread over a factor of four.
  • Solana (since 2026-09-16): the headline is the lag behind the first feed to report the trade, our own node subscription included in the race. Solana has no on-chain timestamp with sub-second precision, so the timestamps providers send compare conventions: Mobula's `date` (its ingestion time) read as a constant 0.10 s, Serialized's `at` (blockTime, whole seconds) as 0.75 s, while against a common clock the two feeds are 10 to 30 ms apart.
  • Solana zero point: no RPC WebSocket we hold, public or keyed (mainnet-beta, Helius, Alchemy), precedes the providers' geyser feeds, so an absolute zero point is not available and the first observation is the ruler. Our node stays in the race: it validates the hash on chain and bounds the field whenever a feed is slower than a plain RPC subscription.
  • Race: every feed's arrival for a transaction is compared to the earliest feed's (exactly one feed wins each trade, the earliest arrival, so the shares add up to 100; trades only one feed reported are not scored). Published on every chain as `head_lag_first_share_pct`, the First to report view: the share of the last 24 h of trades a feed reported before every other feed.
  • Race eligibility (since 2026-10-04): only trades our own pool subscription saw are raced. OKX and Birdeye are subscribed per token and see every pool on it, so the book had filled with trades from pools this bench does not measure, scored as a race between those two alone. After the filter, Solana discards hundreds of thousands of off-pool races an hour and scores of order 100, its rate before those feeds arrived. Feeds seeing only our pool had been divided by a denominator they could not enter.
  • Consequence for the Solana column: `head_lag_seconds` there is the lag behind the first feed in a race, so it moved with the same fix. Figures published before 2026-10-04 for OKX and Birdeye on that column were measured on a wider set of trades than the other four feeds.
  • Solana headline: `head_lag_seconds` is the lag behind the first observation of the trade, our node included, floored at 1 ms. GeckoTerminal polls and lands 15 to 100 s later; it is measured against the same first arrival.
  • Reading a raced column (Solana, BNB Chain, Robinhood Chain): the leading feed's figure is the floor, not a measured latency. Whichever feed wins a race is zero behind itself, published as 1 ms so the row renders. The gap to the next feed is not a speed ratio, it is how far behind the others arrived. Read the leader through First to report and the others through their own lag.
  • Regions: us-east, eu-west, sgp. Cross-region median reported in the headline.
  • Reference on Base: a chain-wide `logs` subscription we hold on Base's sequencer node (`mainnet-preconf.base.org`) in every region, the first sighting of each transaction taken as the zero point. Measured 2026-11-06 against two public Base WebSockets, it saw the transaction first on 99 to 100 percent of about 1,500 trades, with a median lead of 117 and 151 ms.
  • Base Denim (2026-11-05 18:00 UTC) replaced flashblocks with 200 ms canonical blocks and removed the preconfirmed state. Both former reference sources, the flashblock stream and `pendingLogs`, went silent at activation, so no Base trade was scored from 2026-11-05 18:00 UTC until the move to sealed logs on 2026-11-06. Base figures before Denim were measured against flashblock preconfirmations and are not comparable with figures after it.
  • Why BNB Chain moved to the race on 2026-11-01: its reference reported a trade first on 2.99 percent of races, and a sample that beat it was discarded rather than floored. So the fastest feeds were scored only on their slowest trades, 91 percent of two feeds' samples thrown away, and the feed first on 65.53 percent of trades published a worse median than one first on 1.21 percent.
  • Why Robinhood Chain moved the same day: it had no reference at all, and every provider was scored against its own block timestamp. Figures published for either chain before that date are biased upward for the fastest feeds and are not comparable with figures after it.
  • The reference clock is still measured on every chain and still published as a signed series, including the trades where a feed beats it. It is not what ranks the chains that race, because a zero point that arrives after the field cannot bound it, but it is the only measurement that can see the whole field slow down at once, which a race between feeds cannot. It is what detected this.
  • Why Base had two reference sources from 2026-10-29 until Denim: the flashblock endpoint is served through a CDN and carries a tail of 170 to 220 ms on its slowest decile. A reference that is late flatters every provider measured against it, and by late October one provider was arriving before our own reference on more Base races than it lost, so the zero point had stopped bounding the field.
  • Adding that second Base source can only move the zero point earlier, never later, because the clock keeps the first sighting of a transaction and discards the rest. Base head-lag figures published before 2026-10-29 are therefore smaller than the same measurement would be today, by up to the size of that tail. The first-to-report shares are unaffected: that race is between providers, and the reference does not compete in it.
  • Base emissions we cannot match to our reference sighting are dropped rather than measured against a different ruler. Measuring against the block timestamp charged a provider reading preconfirmations with a negative lag, and described the chain's stamping convention rather than the provider's pipeline.
  • Metric: gauge `head_lag_seconds`, scraped every 30 seconds. Aggregated over the 24-hour window using `quantile_over_time`.
  • Success rate: presence ratio. Share of expected sampling slots where a value was actually emitted (2,880 expected per provider per day at the 30 s scrape). 100% means the aggregator's feed was reachable for the full window.
  • Coverage is not the same as presence. Birdeye's stream carries part of the bench pool's flow rather than all of it: 106 of 442 and 13 of 44 pool swaps over two Base windows, about a quarter. Its percentiles therefore describe the trades it does report, and the presence ratio above measures whether the feed was reachable, not how much of the pool it covered.
  • There is no combined view across chains, and the headline is Base. Base is scored against our own node, so its figure is a latency; Solana, BNB Chain and Robinhood Chain are scored as a race, where the winner reads 1 ms because it is zero behind itself. A mean of the four moved when a feed won more races, not when it got faster. Read one chain at a time, and the raced chains through First to report.
  • Cardinality: four aggregators on four chains plus two on three (OKX, Birdeye) is 22 aggregator-chain pairs × 3 regions = 66 active series.
  • Probe placement: the three probes run in their named regions on Railway (europe-west4, us-east4, asia-southeast1). Until 2026-09-15 all three ran in asia-southeast1 under regional labels; region columns before that date are three Singapore vantage points.
  • Codex endpoints: Solana reads Codex's Frankfurt edge node (`fra.edge.codex.io`), Base and Robinhood Chain `iad.edge.codex.io`, from all three regions; BNB Chain reads the standard `graph.codex.io` endpoint. Base and Robinhood Chain figures before the move to `iad.edge.codex.io` read `graph.codex.io`.
  • Codex commitment levels: Solana, Base and Robinhood Chain subscribe at Processed (on Base, until Denim, the flashblock preconfirmation the Base reference also read); BNB Chain at the default. Robinhood Chain figures before the move to `iad.edge.codex.io` read the default level, the only one `graph.codex.io` serves on that chain.
  • Codex auth: the harness authenticates with an API key Codex supplied for this bench. Earlier figures read every chain from `graph.codex.io` with a token minted from a defined.fi web session, Base at the default commitment level.

Results: 6 providers ranked by Head lag (p50, 24h)

Fastest crypto price API, live head lag across 6 data providers: Head lag per provider (p50, 24h).
№Providersp50p90p99First to reportSuccess
1CodexGraphQL feed0.05 s0.06 s0.09 s73.4%97.52% (n=8426)
2SerializedWebSocket trades stream0.09 s0.17 s0.30 s24.0%97.52% (n=8426)
3MobulaWebSocket feed0.12 s0.34 s0.94 s2.54%97.53% (n=8427)
4OKXWebSocket trades stream0.29 s0.69 s1.4 s0.050%97.53% (n=8427)
5BirdeyeWebSocket trades stream0.78 s1.5 s11 s0%97.53% (n=8427)
6GeckoTerminalREST feed24 s1.4 min1.9 min0%61.63% (n=5325)

Frequently asked

Which crypto data API has the lowest latency right now?

It depends on the chain, because each chain's base block cadence sets a different floor. On Solana the leader is Codex at <0.01 s (p50, 24 h). On Base it's Codex at 0.05 s. On BNB Chain it's Serialized at 0.02 s. On Robinhood Chain it's Codex at <0.01 s. Pick a provider based on the chain you are integrating, not a cross-chain average.

What is head lag in a crypto data feed?

Head lag is the wall-clock interval between a transaction landing in a confirmed block on chain and the same transaction appearing on the data provider's feed. A provider with 200 ms head lag pushes the event a fifth of a second after it settled; a provider with 6 s head lag pushes it after six seconds. The number controls how live a trading UI, a chart or a PnL tracker actually feels when the underlying chain moves.

Is WebSocket faster than REST for crypto market data?

Yes, structurally. A WebSocket connection pushes events the moment the provider's indexer has them, so latency tracks the publisher's indexer speed and the network path. REST polling adds the poll interval to every read: a one-second poll cadence puts a floor of one second on top of whatever the indexer adds. The leaderboard shows the difference live, with Mobula on a WebSocket feed, Codex on GraphQL subscriptions and GeckoTerminal on REST.

How fast does GeckoTerminal update prices?

GeckoTerminal currently sits at 24 s (p50, 24 h) head lag on this benchmark. REST endpoints update at the publisher's chosen cadence rather than the moment a swap lands, which is the architectural reason REST polling reads slower than WebSocket feeds for the same underlying chain data.

Why does the Solana leader show a lag near zero?

Because on Solana the ruler is the first feed to report the trade, not the chain. Solana's blockTime has one-second resolution and nothing on chain marks the millisecond a trade became observable, so measuring each provider against the timestamp it sends compared clock conventions: one provider's field was its own ingestion time (a constant 0.10 s), another's the blockTime (0.75 s on average). Against a common clock the two are 10 to 30 ms apart. The First to report view answers the question directly: the share of trades each feed delivered first. Our own node runs in the race and only wins on a small share of trades, which tells you these push feeds beat a plain RPC subscription; an absolute number needs a geyser-grade reference, which no RPC WebSocket we tested provides.

How is head lag measured on OpenChainBench?

On Base the harness holds a log subscription on the sequencer node in every region and timestamps each transaction the first time it appears there. On Solana, BNB Chain and Robinhood Chain the ruler is the first feed to report each trade, so the headline is the lag behind that first arrival and the leading feed reads 1 ms by construction. Every swap is timestamped with millisecond precision; p50, p90 and p99 are aggregated over 24 hours via Prometheus `quantile_over_time`. Errors and dropouts are tracked separately as a presence ratio so a fast feed that disappears does not silently rank above a slower feed that stays up.

Which data provider should I pick for a real-time trading interface?

Read both the p50 and the p99 columns. p50 tells the typical experience, p99 tells the worst minute a user will see when a chain spikes or a region's path degrades. A 500 ms p50 with a 30 s p99 means most of the time the UI feels snappy and once per minute it stutters. The leaderboard splits both, plus the success rate column flags providers whose feed dropped during the measurement window.

Source code github.com/ChainBench/OpenChainBench/tree/main/harnesses/aggregator-head-lag