DEV Community

Cover image for API Response Time vs Event-to-Feed Latency: The Metric Everyone Measures Wrong
orbistats
orbistats

Posted on

API Response Time vs Event-to-Feed Latency: The Metric Everyone Measures Wrong

"Our API responds in 40ms" sounds fast. It also tells you almost nothing about whether your data is actually fresh — and conflating these two numbers is exactly the mistake that gets discovered the hard way, usually after a bad trade or a stale line got shown to a user.

Let's define both metrics precisely, show why they diverge, and write the code to measure the one that actually matters.

Two completely different numbers

API response time — how long your HTTP request takes to get a response, once you make it.

javascript
const start = performance.now();
const res = await fetch("https://api.example.com/v1/odds/fixture_50231");
const data = await res.json();
const responseTime = performance.now() - start;
console.log(API responded in ${responseTime}ms); // e.g. 42ms

This measures your network round-trip and the server's processing time for that single request. It says nothing about how old the data inside that response already was by the time you asked for it.

Event-to-feed latency — the time between something happening in the real world (a goal, a scratch, a line move) and that update reaching your system, regardless of when you happened to ask.

javascript
// This is the number that actually matters — and it's harder to get
const eventTimestamp = data.event_timestamp; // when it happened at the source
const receivedTimestamp = Date.now(); // when you received it
const eventToFeedLatency = receivedTimestamp - eventTimestamp;
console.log(Event-to-feed latency: ${eventToFeedLatency}ms);

The gap between these two numbers is where most vendor claims quietly hide their weakest point.

Why a fast API response can still mean stale data

A technical breakdown of odds-feed freshness makes this distinction precisely: if a sportsbook changed a line 10 seconds ago and your API still shows the old line, your data is 10 seconds stale — and that staleness is completely invisible if you're only measuring how fast the API replied with the (stale) number it had on hand.

The same source breaks total end-to-end latency into three components that compound:

Total latency = collection time + processing time + delivery time

collection time = how often the provider polls the original source
processing time = normalization, storage, internal routing
delivery time = how the update reaches YOU (push vs your poll interval)

Their own provider comparison table makes the gap concrete: one streaming provider delivers updates in under 89ms after detecting a change, with a 3-5 second collection interval, for an effective freshness of roughly 3-5 seconds — while a polling-only provider has no fixed delivery latency at all (because you set your own poll interval), with a 30-60 second collection interval, meaning effective freshness lands at 30-60 seconds plus whatever interval you poll at. Both providers could report a fast "API response time." Only one of them is actually fresh.

Why esports and trading contexts expose this fastest

This gap matters most where decisions are made in milliseconds. Coverage of low-latency esports data feeds for prediction bots frames it directly: a low-latency feed captures events at the engine level — a kill, an objective, a round ending — and pushes structured data to your endpoint in milliseconds, and the advice given to buyers is blunt: insist on documented latency benchmarks before committing to a feed, and test those benchmarks in live conditions during high-traffic events rather than relying solely on vendor-provided figures.

That last point is the crux of this whole post: vendor-provided figures often describe API response time, not event-to-feed latency, and the two get conflated constantly in marketing copy.

How to actually measure event-to-feed latency yourself

You need three things: an accurate event timestamp from the source, an accurate receive timestamp on your side, and clock synchronization you can trust.

javascript
// A minimal latency-measurement harness for a WebSocket feed
const ws = new WebSocket("wss://stream.orbistats.com/v1/live");
const latencySamples = [];

ws.onmessage = (event) => {
const update = JSON.parse(event.data);
const receivedAt = Date.now();

// event_timestamp must come from the provider's source-of-truth clock,
// not re-derived client-side — otherwise you're measuring your own clock drift
const latencyMs = receivedAt - update.event_timestamp;

latencySamples.push(latencyMs);
logLatencyMetric(update.fixture_id, latencyMs);
};

function logLatencyMetric(fixtureId, latencyMs) {
console.log([${fixtureId}] event-to-feed latency: ${latencyMs}ms);
}

For a production trading system, you don't just want the average — you want percentiles, because the worst-case tail is what actually causes bad fills:

python
import numpy as np

def summarize_latency(samples_ms):
return {
"p50": np.percentile(samples_ms, 50),
"p95": np.percentile(samples_ms, 95),
"p99": np.percentile(samples_ms, 99),
"max": max(samples_ms),
"mean": np.mean(samples_ms),
}

A feed averaging 40ms but with a p99 of 800ms is far riskier

for trading logic than one averaging 60ms with a p99 of 90ms

print(summarize_latency(latency_samples))

A well-known principle in trading-latency measurement is exactly this: express latency as percentiles (p50, p95, p99, p99.9) for trading systems, not just averages — because an average hides the tail spikes that actually break your logic during high-volume moments.

The clock-sync problem nobody mentions

If your server's clock and the provider's server clock are even 200ms apart, your "latency" measurement is really "latency ± clock drift" — and you won't know which. This is a documented, real operational question: engineers running production market-data systems specifically ask how to programmatically get the timestamp of when a tick arrived in the API library, precisely so they can use it as a trustworthy base for calculating latency added by their own downstream system, separate from clock-sync noise upstream.

Practical fix: run NTP sync on your infrastructure, and when comparing your own systems, use a monotonic clock instead of wall-clock time to avoid drift entirely:

javascript
// For measuring YOUR OWN internal processing latency (not event-to-feed),
// use a monotonic clock — it can't jump backward or drift like Date.now()
const t0 = process.hrtime.bigint();
await processUpdate(update);
const t1 = process.hrtime.bigint();
const internalProcessingNs = t1 - t0;

For event-to-feed specifically (comparing across systems — provider's clock vs yours), you're stuck relying on synchronized wall-clock time — which is exactly why serious infrastructure benchmarking research on live sports feeds had to devise an entirely separate estimation method using relative delays extracted from archived video, because naive timestamp comparison across independent systems proved unreliable in their own measurements.

What to actually ask a vendor

Given all of this, here's the question that separates a real answer from a marketing number:

"What exactly does your latency figure measure — API response time for a request I initiate, or the time from the real-world event to your feed emitting it? And is that a mean, or a p95/p99?"

A vendor citing a single flat number like "sub-50ms" without specifying which of these it is, or which percentile, hasn't actually answered the question — they've answered a different, easier question.

Where this fits with Orbistats

Every update over our WebSocket API carries a source event timestamp, not just a delivery timestamp, specifically so you can measure event-to-feed latency yourself rather than trusting a single marketing figure — the code above works directly against it. Our odds API and live scores API share the same timestamp discipline, and our research section covers what sub-50ms actually requires end to end, including which component of total latency it refers to. Test the timestamp fields yourself in our public sandbox with no signup, check the API reference for the exact schema, and review our documentation for how collection, processing, and delivery are separated in our architecture. If you're benchmarking us against another vendor for a trading use case, our status page and changelog give you the operational history to cross-check any claim against.

Top comments (0)