Blog Docs Markets Portal Sign up
HomeBlog › Sportsbook Latency Budgets

Sportsbook Latency Budgets: What to Measure and Why It Matters

Engineering 27 May 2026 · 8 min read

Every operational issue in a live sportsbook eventually traces back to a latency budget that nobody wrote down. Here's the one we use, and the four numbers worth monitoring continuously.

The five hops between an upstream change and the user's eyeballs

HopTargetWhat goes wrong
1. Upstream → your origin< 200msProvider's own infra slow; bad peering
2. Origin parse + cache write< 20msJSON parse hot path; Redis SET latency
3. Origin → CDN/edge< 50msCache invalidation delay; tag-purge slow
4. Edge → user's network< 200msUser's ISP, mobile network, distance
5. Browser paint< 30msReact re-render storm; layout thrash

Total budget: < 500ms. Anything more and a 1-second human-perceptible lag creeps in. At 1.5+ seconds, advantage players notice.

The four numbers worth dashboarding

  1. p50 / p95 of "upstream-to-Redis" — measured at your origin. If p95 exceeds 300ms, your provider has a problem.
  2. p50 / p95 of "Redis-to-WebSocket-frame" — measured inside your backend. This is where Node.js GC pauses show up.
  3. p95 of "WebSocket-frame to browser-onmessage" — measured in the browser via Date.now() - serverTs. Includes network + browser.
  4. Time-since-last-update per market — not really a latency, but it tells you when a market has silently gone stale.

How to measure each hop without spending two weeks on it

Hop 1: upstream → origin

Stamp the upstream's server timestamp (every Euro365 outcome ships ts as the last field — see docs). Diff against your own server clock at the moment you ingested it. Don't use NTP-naive clocks; the diff is small enough that 100ms of clock drift will dominate.

Hop 2: origin internal latency

Wrap the parse-and-store path in a timing block. We use Prometheus histograms; for smaller setups a single in-memory ring buffer + p95 calc every minute is enough.

Hop 3: edge propagation

If you're behind Cloudflare/Fastly, this is the cache-purge delay. Most operators don't realize their "real-time" feed is being cached for 5 seconds at the edge until they look. Cache-Control: private, no-cache on push channels; max-age=2 on poll endpoints.

Hop 4–5: client side

Send the server timestamp inside the WebSocket frame; on the client log performance.now() - frame.ts and bucket by user agent. You'll quickly see that 90% of latency above your budget is one specific mobile carrier in one specific country — and you can't do much about that one.

What "good" looks like in production

MetricGoodTrouble
Upstream → origin p95< 200ms> 500ms
Origin → edge p95< 100ms> 300ms
Edge → browser p95< 250ms> 600ms
End-to-end p95< 500ms> 1500ms

The one mistake we see most

Teams optimize hops 1–3 to perfection — Redis tuned, edge purges instant — then hop 5 (React re-render) takes 800ms because every odds change triggers a full tree re-render. The browser is part of the latency budget; measure it before you blame the API.

Get a free API key Read the docs