How live sports scores update in real time
How sports apps deliver sub-second score updates to millions of concurrent users using WebSocket fan-out, server-sent events, and intelligent client polling with delta compression.
The Problem Statement
Interviewer: "You are watching a live football match on a sports app. The moment a goal is scored in the stadium, the score on your phone updates almost instantly, along with millions of other users' phones. Walk me through how that works. How does the data get from the stadium to your screen in under a second?"
This question tests your understanding of real-time data pipelines at massive scale. The interviewer is looking for three things: how structured event data flows from a physical venue through ingestion systems to application servers, how you fan out a single event to millions of concurrent connections without melting your infrastructure, and whether you can reason about the bandwidth and connection management challenges of persistent connections at scale.
I find this question particularly interesting because it combines two hard problems. The first is data ingestion: turning a referee's whistle into a structured JSON event within hundreds of milliseconds. The second is fan-out: delivering that event to 100 million concurrent viewers in under a second. Each problem alone is manageable. Combined, they create architectural constraints that force real tradeoffs between latency, cost, and reliability.
The same patterns appear in stock tickers, live election results, multiplayer game state sync, and any system where millions of users need the same data at the same time. Once you understand the sports score architecture, you have a template for all broadcast-style real-time systems.
Clarifying the Scenario
You: "Before I design this, I want to scope the problem properly."
You: "When you say 'real time,' what latency budget are we targeting? Sub-second from the event happening in the stadium to the user's screen?"
Interviewer: "Under 2 seconds end-to-end for score changes. Clock updates can be slightly slower."
You: "How many concurrent users at peak? Are we talking regular season games or Super Bowl scale?"
Interviewer: "Design for Super Bowl scale. 100 million concurrent viewers, all wanting live updates."
You: "Should I cover just score updates, or the full event stream: substitutions, cards, play-by-play?"
Interviewer: "Full event stream. Score changes are the highest priority, but users see everything."
You: "Got it. I will structure my answer in three parts: how data gets from the stadium to our servers, how we fan out events to millions of concurrent connections, and how we optimize bandwidth using delta compression so we are not sending the full scoreboard on every update."
Interviewer: "Good structure. Start from the stadium."
Setting the latency budget early is critical. "Real time" means different things to different people. A 2-second budget for score changes gives us room for network jitter, but not for batch processing or polling delays. This constraint eliminates any design based on periodic API polling.
My Approach
I break this into four areas:
- Data ingestion pipeline: How a goal in the stadium becomes a structured event on our servers within 500ms
- Fan-out to millions: How a single event reaches 100M concurrent WebSocket connections without running 100M individual pushes from one server
- Delta compression: How we minimize bandwidth by sending only what changed, not the entire scoreboard every time
- Connection management: How we handle millions of persistent connections, graceful degradation for clients that cannot maintain WebSockets, and mobile-specific challenges
The core insight is that this is a broadcast problem, not a request-response problem. Every connected user receives the same data at the same time. That means we can use hierarchical fan-out (like a tree) instead of point-to-point delivery. One server tells 100 edge servers, each edge server tells 1 million clients. The event is copied at each tier, not sent individually from a central server.
Think of it like a stadium announcer using a PA system versus individually whispering the score to each fan. The announcer speaks once. The speakers (edge servers) amplify the message. Every fan hears it simultaneously.
Numbers at a glance
| Metric | Approximate value |
|---|---|
| Concurrent users (Super Bowl peak) | 100-150 million |
| Events per game (football) | 200-500 structured events |
| Score change events per game | 4-12 (goals, touchdowns, etc.) |
| Event payload size (delta) | 200-500 bytes |
| Full scoreboard payload | 2-5 KB |
| Target end-to-end latency | Under 2 seconds |
| WebSocket connections per edge server | 500K-1M |
| Edge servers needed at peak | 100-300 |
| Data provider webhook latency | 100-300ms from live event |
Scale context: why this is a broadcast problem
During the 2024 Super Bowl, over 120 million viewers watched simultaneously. If each viewer's app polls your API every 5 seconds, that is 24 million requests per second. A typical API server handles 10,000 requests per second. You would need 2,400 API servers just for polling, and 80% of responses would be "nothing changed." WebSocket push eliminates this entirely: you send data only when something actually happens.
The Architecture
Here is the full pipeline from stadium event to user's screen.
Let me walk through the critical path. When a goal is scored, the official scorer in the stadium enters it into the data provider's system (Sportradar, Opta, or Stats Perform). The data provider's system generates a structured JSON event and sends it to our webhook endpoint within 100-300ms of the live event. Our ingestion layer validates, deduplicates, normalizes the event, and publishes it to a Kafka topic partitioned by game ID. The fan-out layer consumes from Kafka and pushes the event to all edge servers that have subscribers for that game. Each edge server pushes the event to its connected clients via WebSocket.
Total latency budget: 200ms (provider) + 50ms (ingestion) + 50ms (Kafka to router) + 50ms (router to edge) + 50ms (edge to client) = roughly 400-600ms in the happy path. Well within our 2-second budget, with room for network jitter.
The key architectural decision is the hierarchical fan-out. The Kafka consumer (router) does not push to 100 million clients directly. It pushes to 200 edge servers. Each edge server is responsible for its own pool of 500K connections. This is the tree-shaped broadcast that makes the math work.
Common mistake: single-tier fan-out
Candidates often draw a single WebSocket server that pushes to all clients. At 100M connections, even if each push takes 1 microsecond, broadcasting to all clients from one server takes 100 seconds. Hierarchical fan-out (router to edge servers to clients) is essential. Think of it as a CDN for real-time events.
Deep Dive 1: The Data Ingestion Pipeline: From Stadium to Server
The journey from a real-world event to a structured data event is more complex than most engineers realize. There is a human in the loop, and the data passes through a third-party provider before reaching your infrastructure.
The data provider is a critical dependency. Companies like Sportradar have operators physically present at every major sporting venue. These operators watch the game and enter events in real time using specialized software. The provider's system validates the event against the current game state (you cannot score a goal during halftime), assigns a unique event ID and UTC timestamp, and pushes it to your webhook within 100-300ms.
Event types and priorities
Not all events are equal. Score changes are the highest priority and should be delivered with the lowest latency. Clock updates are lower priority and can tolerate slightly higher latency. Here is the priority model I would use:
| Priority | Event types | Latency target | Delivery guarantee |
|---|---|---|---|
| P0 (critical) | Score change, game start, game end | Under 1 second | At-least-once, ordered |
| P1 (high) | Cards, substitutions, penalties | Under 2 seconds | At-least-once |
| P2 (medium) | Play-by-play, possession changes | Under 5 seconds | Best-effort |
| P3 (low) | Clock tick, statistics updates | Under 10 seconds | Best-effort, batched |
P0 events bypass any batching or aggregation. They flow through the pipeline immediately. P3 events (like clock ticks every second) are batched into 5-second windows to reduce fan-out volume. This priority system is how you prevent a flood of possession-change events from delaying score update delivery.
Deduplication
Data providers sometimes send duplicate events (network retry, provider-side retry). The webhook receiver tracks seen event IDs in a Redis set with a 1-hour TTL. If an event ID has been seen before, the receiver drops it. This is cheap and effective because event IDs are small strings and the deduplication window only needs to cover the retry period.
Key insight: the data provider is the bottleneck you cannot control
Your entire pipeline can be under 200ms, but if the data provider takes 5 seconds to enter and transmit the event, your users see it 5 seconds late. In practice, top-tier providers like Sportradar deliver events within 100-500ms of the live action. When evaluating providers, latency is the most important SLA to negotiate. Some platforms use multiple providers simultaneously and race the events, taking whichever arrives first.
Deep Dive 2: Fan-Out to Millions of Concurrent Users
The hardest engineering problem in this system is not receiving events. It is delivering a single event to 100 million connected clients in under a second. This is the fan-out challenge.
The fan-out happens in two tiers. Tier 1: the Kafka consumer publishes the event to a Redis Pub/Sub channel named after the game ID. Every edge server that has clients subscribed to that game listens on that channel. Redis Pub/Sub delivers the message to all subscribers in microseconds. Tier 2: each edge server iterates through its local subscriber list for that game and pushes the event to each WebSocket connection.
Connection management at scale
A single Linux server can handle 500K-1M concurrent WebSocket connections with proper tuning (ulimit -n, net.core.somaxconn, tcp_tw_reuse). The bottleneck is not memory (each connection uses roughly 2-4 KB of kernel buffer), but CPU for serializing and writing messages to each socket.
At 100M concurrent connections, you need 100-200 edge servers. These are distributed geographically: US-East, US-West, EU-West, AP-South, etc. Users connect to the nearest edge server via DNS-based routing or an anycast IP. This reduces latency and distributes the connection load.
Channel-based subscription
When a user opens the "Game A Live" page, their client establishes a WebSocket connection to the nearest edge server and sends a subscription message: {"subscribe": "game:12345"}. The edge server adds that connection to its local subscriber set for game 12345. When an event arrives for game 12345 via Redis Pub/Sub, the edge server iterates through the subscriber set and writes the event to each connection.
This is efficient because:
- Only clients watching Game A receive Game A events (no wasted bandwidth for irrelevant games)
- The subscription state is local to each edge server (no distributed subscription registry needed)
- Adding/removing subscriptions is O(1) on a hash set
Delivery protocol hierarchy
Not every client can maintain a WebSocket connection. Corporate firewalls, proxy servers, and some mobile networks block WebSocket upgrades. I design a protocol hierarchy with automatic fallback:
| Protocol | Best for | Latency | Server cost | Limitation |
|---|---|---|---|---|
| WebSocket | Modern browsers, mobile apps | 50-100ms | Medium (persistent connections) | Blocked by some proxies |
| Server-Sent Events (SSE) | Restricted networks, simpler clients | 100-200ms | Low (HTTP-based, one-directional) | No binary data, browser limit of 6 connections |
| Long-polling | Legacy clients, extreme fallback | 1-5 seconds | High (repeated HTTP requests) | Higher latency, more server load |
The client tries WebSocket first. If the connection upgrade fails (HTTP 403 or timeout), it falls back to SSE. If SSE also fails, it falls back to long-polling with a 5-second interval. This graceful degradation ensures every client gets updates, with the best possible latency for their network environment.
Deep Dive 3: Delta Compression and Bandwidth Optimization
When 100 million users are connected simultaneously, every byte matters. Sending the full scoreboard (2-5 KB) on every event wastes bandwidth. Most events change only one or two fields. Delta compression sends only what changed.
The protocol works in three modes:
- Snapshot: Sent when a client first connects or falls too far behind. Contains the complete game state. Roughly 2-5 KB.
- Delta: Sent for each event. Contains only the fields that changed, plus a sequence number. Roughly 200-500 bytes.
- Delta batch: Sent when a client reconnects and missed a few events. Contains an ordered list of deltas from the client's last known sequence number.
Sequence numbers for ordering
Every event gets a monotonically increasing sequence number within a game. The client tracks the last sequence number it received. If it receives seq 48 after seq 46 (missed 47), it requests a re-sync from seq 47. The edge server maintains a sliding window of recent deltas (last 100 events per game) in memory. If the client's last sequence is within the window, send the missing deltas. If it is too far behind (e.g., reconnecting after 30 minutes), send a full snapshot.
This is the same pattern used in operational transform (Google Docs), video game netcode, and database replication. Sequence numbers with re-sync are the universal answer to "what if I missed something."
Bandwidth math
Let me do the math to show why delta compression matters:
- Without compression: 100M users x 200 events per game x 3 KB per event = 60 TB per game. That is roughly $5,000 in bandwidth cost per game.
- With delta compression: 100M users x 200 events x 300 bytes per delta = 6 TB per game. Ten times cheaper.
- With batched clock ticks: Clock ticks (every second for 90 minutes = 5,400 events) are batched into 5-second windows, reducing clock events from 5,400 to 1,080. Further savings.
For mobile users on cellular, bandwidth is even more precious. I would also apply gzip compression on the WebSocket frames, which typically achieves 60-80% compression on JSON payloads.
Production example: ESPN's real-time architecture
ESPN serves live scores to over 50 million concurrent users during major events. They use a combination of WebSocket push for their app, SSE for web browsers, and edge-cached polling endpoints for third-party embeds. Their pipeline processes over 10,000 events per second across all concurrent games, with a median delivery latency of 300ms from data provider to client.
The Tricky Parts
-
Mobile connection instability: Mobile users switch between WiFi and cellular, go through tunnels, and have intermittent connectivity. The WebSocket connection drops and must be re-established. The client needs automatic reconnection with exponential backoff, and the re-sync protocol (sequence numbers) ensures no events are lost during the gap. I would also cache the last known game state locally so the UI does not flash to a loading state on every reconnection.
-
Thundering herd on game start: When a major game starts, millions of users open the app simultaneously. All of them need to establish WebSocket connections and request initial snapshots at the same time. Without connection rate limiting, edge servers will be overwhelmed. I would use a jittered connection window: the client adds a random delay of 0-5 seconds before connecting, spreading the thundering herd over a few seconds.
-
Multi-game scoreboards: A user watching a "scoreboard" page sees live updates for 15 games simultaneously. Subscribing to 15 channels per connection multiplies the fan-out work on the edge server. I would aggregate events for "scoreboard" subscribers: instead of pushing every event for every game individually, batch all events from the last second into a single "scoreboard update" message. This reduces per-client pushes from potentially dozens per second to one per second.
-
Event ordering across providers: If you use multiple data providers for redundancy and race their events, you may receive them out of order. Provider A sends "goal at minute 73" before Provider B sends "corner kick at minute 72." Your normalizer must re-order events by game clock, not by arrival time. A short buffer (500ms) at the normalizer allows events to arrive and be sorted before publishing.
-
Data provider failure: If Sportradar's feed goes down mid-game, you have zero new events. The fallback is a secondary provider (Opta) that you switch to automatically. If both fail, the last resort is manual entry by your own operators watching the broadcast, but this adds 10-30 seconds of latency. Having a "last updated" timestamp visible to users manages expectations during outages.
-
Push notification for key events: Not every user has the app open. Users who "follow" a team but are not actively watching should receive a mobile push notification for goals and game-ending events. This is a separate pipeline: the event router publishes P0 events to a push notification service (Firebase Cloud Messaging, APNs) that handles delivery to offline devices. The push notification includes just enough data to update the lock screen widget.
Do not conflate push notifications with WebSocket push
WebSocket push is for live, in-app updates to active users. Mobile push notifications (FCM/APNs) are for reaching users whose app is closed. They use completely different infrastructure, have different latency characteristics (push notifications can take 1-10 seconds), and different rate limits (APNs throttles per device). Design them as separate systems that share the same event source.
What Most People Get Wrong
| Mistake | What they say | Why it is wrong | What to say instead |
|---|---|---|---|
| Polling-first design | "Clients poll the API every second" | 100M users x 1 req/sec = 100M QPS, mostly wasted | "WebSocket push with SSE and polling as fallbacks" |
| Single-tier fan-out | "The server pushes to all clients" | One server cannot iterate 100M connections in under a second | "Hierarchical fan-out: router to edge servers to clients" |
| Ignoring the data source | "Events come from our system" | You do not generate sports data; third-party providers do | "Sportradar/Opta webhook with HMAC verification and dedup" |
| Full state on every push | "Send the complete scoreboard" | 3KB x 100M users x 200 events = 60 TB per game | "Delta compression with sequence numbers for gap detection" |
| No fallback for WebSocket | "Everyone uses WebSocket" | Corporate proxies and mobile networks block WS upgrades | "WebSocket first, SSE fallback, long-poll last resort" |
How I Would Communicate This in an Interview
Here is how I would actually say this:
"The pipeline has three stages: ingestion, fan-out, and delivery.
For ingestion, sports data comes from third-party providers like Sportradar. They have operators at every venue who enter events in real time. The provider sends us the event via a signed webhook within 200ms of it happening. Our ingestion layer validates the signature, deduplicates by event ID, normalizes the event into a unified format across sports, and publishes it to a Kafka topic partitioned by game ID.
For fan-out, I would not have clients poll. At Super Bowl scale (100M concurrent users), polling generates 50M+ requests per second with 95% returning 'no change.' Instead, clients maintain WebSocket connections to dedicated edge servers. When an event arrives, the Kafka consumer publishes it to Redis Pub/Sub on a channel named after the game. Every edge server subscribed to that game receives the event and pushes it to its local WebSocket connections. This is a two-tier fan-out: one event becomes 200 edge server pushes, each of which becomes 500K client pushes.
For bandwidth, I use delta compression. On first connect, the client gets a full snapshot. After that, each event is a delta containing only changed fields plus a sequence number. If the client detects a gap in sequence numbers (missed event due to disconnection), it requests a re-sync. The edge server maintains a sliding window of recent deltas for efficient re-sync.
The fallback hierarchy is WebSocket first, Server-Sent Events if WebSocket fails, and long-polling as a last resort. For users not in the app, key events trigger mobile push notifications through FCM/APNs as a separate pipeline."
Interview Cheat Sheet
- "Where does the data come from?" Say: third-party data providers (Sportradar, Opta) have operators at venues who enter events in real time; they push to our webhook within 200ms.
- "Why not poll for updates?" Say: at 100M users, polling generates 50M+ QPS with 95% returning no change; WebSocket push sends data only when something happens, eliminating wasted requests.
- "How do you handle 100M concurrent connections?" Say: hierarchical fan-out with dedicated edge servers; each edge server holds 500K-1M connections; Redis Pub/Sub distributes events from Kafka to all edge servers in microseconds.
- "What if WebSocket is blocked?" Say: protocol fallback hierarchy: WebSocket first, SSE second, long-polling third; client detects and falls back automatically.
- "How do you save bandwidth?" Say: delta compression; send only changed fields plus sequence numbers; full snapshots only on initial connect or if client falls too far behind.
- "What if the client misses an event?" Say: sequence numbers on every delta; client detects gaps and requests re-sync; edge server maintains a sliding window of recent deltas for efficient catch-up.
- "What if the data provider goes down?" Say: multi-provider redundancy; race events from two providers, take whichever arrives first; if both fail, manual fallback with degraded latency.
- "How do you handle game start thundering herd?" Say: jittered connection window; clients add random 0-5 second delay before connecting; pre-warm edge servers for major events.
- "What about users not in the app?" Say: separate push notification pipeline via FCM/APNs for key events (goals, game end); different infrastructure, different latency guarantees.
- "What is the latency budget?" Say: 200ms provider to webhook, 50ms ingestion, 100ms Kafka to edge, 50ms edge to client; total 400-600ms typical, well under the 2-second target.
Test Your Understanding
Q1. During the Super Bowl halftime show, 80 million users close the sports app. When the second half starts, they all reopen it within 30 seconds. Each client needs to re-establish a WebSocket connection and receive a full game state snapshot. How do you prevent this from crashing your edge servers?
Q2. A user's app shows the score as 21-14, but the actual score is 21-21. The user missed a score update because their WebSocket connection dropped briefly during a tunnel. How does the system detect and fix this without the user manually refreshing?
Q3. You are using Redis Pub/Sub to fan out events from the router to edge servers. Redis Pub/Sub has no message persistence: if an edge server is temporarily disconnected from Redis (network blip), it misses any events published during the gap. How do you handle this?
Q4. Your system processes events from two data providers simultaneously for redundancy. Provider A sends a "touchdown" event 300ms before Provider B sends the same event. How do you prevent sending duplicate score updates to users?
Q5. A major soccer match has 50 million viewers. During normal play, you send about 1 event per second (possession changes, fouls). But when a goal is scored, you send a burst of 5 events in 500ms (goal event, updated score, scorer details, assist details, celebration replay timestamp). Some edge servers report packet loss under this burst. How do you smooth this out?
Q6. Your edge servers are in four regions (US-East, US-West, EU-West, Asia). A user in the US is watching a Premier League match happening in England. The data provider sends the webhook to your US-East ingestion endpoint. The event must reach the user connected to a US-West edge server. What is the latency for each hop, and where is the biggest bottleneck?
Q7. Your system sends push notifications for goals to users who follow a team but do not have the app open. During a Champions League night with 8 simultaneous matches, 6 goals are scored within a 2-minute window. A user following all 8 teams gets 6 push notifications in rapid succession. The user complains about notification spam. How do you fix this?
Q8. Your company decides to add live betting odds to the sports score feed. A betting company provides odds that update every 100ms. This is 10x the event volume of score updates. How does this affect your architecture, and what would you change?
Quick Recap
- Live sports data comes from third-party providers (Sportradar, Opta) who have operators at venues entering events in real time, delivering via webhook within 200-500ms.
- The ingestion layer validates HMAC signatures, deduplicates by event ID, normalizes across sports, and publishes to Kafka partitioned by game ID.
- Fan-out uses a hierarchical two-tier model: Kafka to Redis Pub/Sub to edge servers to clients, turning one event into millions of client pushes without any single server handling all connections.
- Dedicated edge servers handle 500K-1M WebSocket connections each, separate from application servers, and are geographically distributed.
- Delta compression sends only changed fields with sequence numbers, reducing bandwidth by 10x compared to full-state pushes, with snapshot fallback for reconnecting clients.
- The protocol fallback hierarchy (WebSocket, SSE, long-polling) ensures every client gets updates regardless of network restrictions.
- Mobile push notifications for key events use a separate pipeline (FCM/APNs) for users who do not have the app open.
- The human operator at the stadium is the largest source of latency in the entire pipeline, dwarfing all network and processing delays combined.
Related Concepts
- WebSocket architecture: The persistent connection protocol that enables server-push without polling, used here for the last-mile delivery to clients.
- Pub/Sub and message fan-out: Redis Pub/Sub and Kafka's topic model are the distribution backbone, the same patterns used in chat systems, notification pipelines, and collaborative editing.
- CDN edge computing: Edge servers for WebSocket connections are conceptually similar to CDN edge nodes: stateless, geographically distributed, and handling the last-mile delivery.
- Event sourcing: The sequence-numbered delta model is a lightweight form of event sourcing, where the current state is reconstructed from an ordered log of events.
- Operational Transform and CRDTs: The "detect gaps, re-sync" protocol used here for score updates is a simplified version of the conflict resolution protocols used in Google Docs and collaborative editors.
title: "How live sports scores update in under one second" description: "How sports data providers push sub-second score updates to apps using WebSockets, SSE, server push, and edge-cached fallback polling for millions of concurrent viewers." tags:
- "situational"
- "sports"
- "realtime"
- "websockets" difficulty: "medium" category: "situational/architecture" order: 124 publishedAt: "2026-04-12" relatedArticles: []
The Problem Statement
Interviewer: "You are watching a live football match on your phone. The ball goes into the net and your app updates the score before you even hear the crowd react on the broadcast. How does that work? Walk me through the full pipeline from the stadium to the user's screen, and explain how you deliver sub-second updates to 10 million concurrent viewers."
This question tests three things: your understanding of real-time data ingestion and processing pipelines, your knowledge of push-based delivery mechanisms (WebSockets, Server-Sent Events, long polling) and their tradeoffs, and whether you can reason about fan-out at massive scale using edge infrastructure.
The common mistake is to skip the data ingestion side and jump straight to "use WebSockets." Strong candidates cover the full pipeline: how score data originates at the stadium, how it flows through a processing layer, and how the fan-out architecture delivers updates to millions of concurrent connections without melting the backend.
Clarifying the Scenario
You: "Great question. Let me make sure I understand the scope."
You: "When you say 'sub-second,' do you mean the total latency from the event happening on the field to the user seeing it on their screen? Or the server-to-client delivery latency?"
Interviewer: "End to end. From the goal being scored to the app showing the updated score."
You: "Got it. And 10 million concurrent viewers, are those all watching the same match or spread across multiple matches happening simultaneously?"
Interviewer: "Peak is during a major event like a World Cup final, so mostly one match, but the system should handle hundreds of concurrent matches."
You: "Should I also cover graceful degradation? For example, what happens when a user is on a poor mobile connection, or when WebSocket connections fail?"
Interviewer: "Yes, that is an important edge case."
You: "I will structure my answer in three parts: the data ingestion pipeline from the stadium to our servers, the fan-out architecture that pushes updates to millions of concurrent connections, and the graceful degradation strategy that handles connection failures and network variability."
My Approach
I think about live sports scores as a three-stage pipeline:
- Data ingestion: How score events originate at the stadium (optical tracking, manual operators, data feed providers) and flow into our processing layer
- Event processing: How raw events are validated, enriched, and normalized before distribution
- Fan-out delivery: How processed events reach 10 million concurrent viewers using WebSockets, SSE, and edge infrastructure
The key challenge is not the WebSocket protocol (that is the easy part). The hard part is fan-out: getting one event to 10 million clients without overwhelming any single server. A single WebSocket server handles roughly 50K-100K connections. For 10 million viewers, you need at least 100 servers just for the connection layer. The question is how to route a single score update to all of them with minimal latency.
I also think about this system as having two very different consistency requirements. The score must be correct (you cannot show a wrong score), but it does not need to be perfectly synchronized across all viewers. If one user sees the goal 200ms before another, that is acceptable. This relaxed consistency requirement is what makes sub-second delivery feasible at scale.
The analogy I use: think of a stadium PA system. The announcer says "GOAL" once (that is the origin publish). The speakers throughout the stadium each broadcast to their local section (that is the edge fan-out). Every fan hears it within a second, but not at the exact same millisecond. Nobody cares about the slight timing difference. Our digital system works the same way.
Sports data is a surprisingly large industry. Companies like Sportradar and Genius Sports employ thousands of operators and deploy tracking hardware in stadiums worldwide. They sell sub-second data feeds to betting platforms, apps, and broadcasters. The data pipeline from stadium to user is already built as a commercial product.
The Architecture
Here is the full system from stadium to user's screen. The key architectural decision is the edge layer: score updates are pushed to edge servers close to users, and those edge servers handle the fan-out to connected clients. This keeps the origin server load constant regardless of viewer count.
Here is how a score update flows through the system:
Step 1: Event originates at the stadium. When a goal is scored, the data comes from multiple sources simultaneously. Optical tracking systems (like Hawk-Eye) detect the ball crossing the goal line within 50ms. Manual operators watching the match confirm the event and enter it within 1-3 seconds. The official data feed provider (Sportradar, Genius Sports) aggregates these sources, validates the event, and publishes a normalized JSON event.
Step 2: Ingestion gateway receives the event. Our ingestion gateway receives the event from the data feed provider. It deduplicates (the same goal may arrive from multiple sources) and validates (score transitions must be sequential, you cannot go from 1-0 to 3-0). This validation step is critical because displaying a wrong score, even briefly, destroys user trust.
Step 3: Event enricher adds context. The enricher adds match context: current minute, scorer name, match statistics, standings impact. This transforms a raw "score changed" event into a rich payload the client can render immediately without making additional API calls.
Step 4: Pub/sub broadcasts to edge servers. The enriched event is published to a pub/sub broker (Redis Pub/Sub for simplicity, Kafka for durability). Each edge server subscribes to the topics for matches its connected clients are watching. A single publish reaches all relevant edge servers.
Step 5: Edge servers push to clients. Each edge server maintains WebSocket (or SSE) connections to its local clients. When it receives a score update, it pushes the event to every connected client watching that match. A CDN-cached HTTP endpoint is also updated for polling fallback clients. The total delivery latency from origin publish to client receipt is 100-200ms.
For your interview: emphasize the edge fan-out architecture. This is the key insight that makes the system scalable. The origin processes one event, the edge layer handles the fan-out to millions. Memorize that sentence.
The Data Ingestion Pipeline from Stadium to Server
The part most engineers overlook is how data gets from a physical stadium to a digital system. This is not a simple API call. It involves hardware, human operators, and multiple validation layers.
There are three levels of data quality in sports:
Tier 1: Automated tracking (50-200ms). Systems like Hawk-Eye, Second Spectrum, and TRACAB use cameras mounted around the stadium to track ball and player positions at 25-50 frames per second. These systems detect goals, offsides, and key events automatically. The latency from physical event to digital signal is under 50ms. This is the fastest source but limited to detectable physical events.
Tier 2: Semi-automated with human confirmation (1-3 seconds). Trained operators watch the match live (often with camera feeds, not broadcast) and input events using specialized software. They capture events that tracking cannot (yellow cards, substitutions, tactical changes). Each event goes through a two-person validation: one operator inputs, another confirms. This adds latency but ensures accuracy.
Tier 3: Broadcast-derived (5-30 seconds). Parsing the broadcast feed for on-screen graphics or commentary. This is the slowest and least reliable source, used only as a fallback for leagues that do not have in-stadium tracking. Some smaller leagues and lower divisions still rely on this as their primary electronic data source.
The key takeaway for your interview: knowing these data tiers shows real-world awareness. Most candidates assume score data magically appears via an API. Mentioning optical tracking, human operators, and the validation pipeline immediately separates you from the crowd.
Never trust a single data source for score events. I have seen cases where a data provider sent a goal event that was called back by VAR 30 seconds later. If you publish without validation, millions of users see a wrong score. Build a short validation delay (100-500ms) for critical events to allow source cross-validation.
Fan-Out to Millions of Concurrent Connections
This is the core scaling challenge. One score update needs to reach 10 million connected clients. If you push from a single server, it is impossible: even at 10 microseconds per WebSocket write, 10 million writes take 100 seconds. The solution is a tree-shaped fan-out using edge servers.
The math works out cleanly. Each edge server maintains approximately 50,000 concurrent WebSocket connections (this is well within the capacity of a modern server with tuned file descriptors and 16GB RAM). For 10 million viewers, you need 200 edge servers. The origin publishes one event to the pub/sub topic. Each of the 200 edge servers receives the event and pushes to its 50K local connections. Total fan-out: 1 publish becomes 200 receives and 10 million client pushes.
The time to push to 50K connections on a single server is roughly 50-100ms (writing to each WebSocket is a buffered I/O operation, and the OS kernel handles the actual TCP sends using writev/sendmsg batching). So the total end-to-end latency from origin publish to all clients receiving the update is approximately 100-200ms for the edge fan-out, plus the ingestion latency from the stadium.
I think of this as a tree-shaped amplifier: one event at the root, 200 edge nodes in the middle, 10 million leaves at the bottom. The amplification ratio is enormous, but the root (origin) does almost no work.
Why edge servers, not origin servers? Two reasons. First, geography: an edge server in London delivers to UK viewers with 10-20ms network latency. An origin in US-East adds 80-100ms of ocean-crossing latency. Second, isolation: if one edge server crashes, only 50K clients are affected. They reconnect to another edge server. If the origin crashes, the entire system goes dark.
Connection routing: When a client opens the app, it connects to the nearest edge server (via DNS-based routing or an anycast IP). The client sends a "subscribe" message for the match it is watching. The edge server joins the pub/sub topic for that match. When the client changes matches, the edge server unsubscribes from the old topic and subscribes to the new one. No reconnection needed.
Memory budget per connection: Each WebSocket connection typically consumes 10-20KB of server memory (kernel buffers, application state, WebSocket frame overhead). At 50K connections, that is about 500MB-1GB. A 16GB server has ample headroom. The real bottleneck is file descriptors, which need to be tuned to at least 65K via ulimit -n.
Memory per connection: Each WebSocket connection consumes roughly 10-20KB of server memory (receive buffer, send buffer, connection state). At 50K connections, that is 500MB-1GB per server. With 16GB RAM, you have ample headroom for the application logic, pub/sub client, and OS overhead. The bottleneck is usually file descriptors, not memory.
The key sentence for your interview: "The origin processes one event. The edge layer handles fan-out to millions. This keeps origin load constant regardless of viewer count." This shows you understand the fundamental scaling principle.
Graceful Degradation from WebSocket to Polling
Not every client can maintain a persistent WebSocket connection. Mobile networks are unreliable, corporate firewalls block WebSocket upgrades, and some browsers have connection limits. The system must degrade gracefully from the fastest delivery mechanism to slower but more reliable alternatives.
The fallback hierarchy:
| Mechanism | Latency | Reliability | Resource cost | Use when |
|---|---|---|---|---|
| WebSocket | < 200ms | Medium (connection drops) | High (persistent conn) | Stable connection, real-time needed |
| Server-Sent Events | < 500ms | High (auto-reconnect) | Medium (HTTP stream) | Server-to-client only, fallback for WS |
| Short polling | 2-5s | Very high (stateless) | Low per request, high aggregate | WS and SSE both fail, corporate proxy |
The client implements progressive fallback:
- On app open, attempt WebSocket connection to nearest edge server.
- If WebSocket fails (corporate proxy, blocked port), fall back to SSE over standard HTTP.
- If SSE fails (some reverse proxies buffer streaming responses), fall back to polling the CDN-cached endpoint every 2 seconds.
- Always maintain a polling baseline: even with an active WebSocket, poll every 30 seconds as a consistency check to catch missed updates.
SSE (Server-Sent Events) is underrated for sports scores. It works over standard HTTP, auto-reconnects with Last-Event-ID, passes through proxies, and requires no special server infrastructure. For a system that only needs server-to-client push (score updates flow one direction), SSE is simpler and more reliable than WebSockets. I would pick SSE as the primary transport unless the product also needs real-time chat or interactive features alongside scores.
The Tricky Parts
-
Event ordering and deduplication. Score events might arrive out of order from different data sources. Client A sees "2-1" then "1-1" (if the original goal is scored, a quick second goal follows, but the second event arrives first from a different source). Every event needs a monotonically increasing sequence number per match. Clients must enforce ordering: if they receive sequence 5 after already processing sequence 6, they ignore it.
-
Connection storms after edge server restarts. When an edge server restarts, 50K clients simultaneously attempt to reconnect. If they all reconnect at the same instant, the new server is overwhelmed. The fix is jittered reconnection: clients wait a random delay (0-5 seconds) before reconnecting. The WebSocket client library should implement this with exponential backoff and jitter.
-
Hot matches vs cold matches. During a World Cup final, one match has 10 million viewers. During a regular league day, you have 200 matches with 10K viewers each. The edge infrastructure must handle both: heavy fan-out for hot matches (more edge servers subscribing to the same topic) and efficient connection sharing for cold matches (many topics per edge server).
-
Score corrections and VAR delays. Video Assistant Referee (VAR) reviews can overturn a goal minutes after it was initially scored. Your system has already pushed the goal to 10 million clients. Now you must push a correction. This requires the client to handle "undo" events gracefully: show a notification that the goal was disallowed, animate the score reversal, and update all derived data (standings, statistics).
-
Time synchronization across clients. A match has a running clock. If clients show different match times, the experience feels broken. But you cannot send a clock tick every second to 10 million clients (that is 10M messages/second of overhead). The solution: send the match clock reference time at kickoff and on resume, let the client render locally. Sync adjustments are sent only during stoppages or when drift exceeds 2 seconds.
-
Betting market integrity. Many sports apps also power live betting. If your score feed is even 500ms ahead of a competitor's, arbitrage bots can exploit the difference. Data providers often contractually require that all consumers receive data at the same time (or within a window). This means your edge fan-out cannot favor certain regions or clients, and you must monitor delivery latency distribution carefully.
What Most People Get Wrong
| Mistake | What they say | Why it is wrong | What to say instead |
|---|---|---|---|
| Skip data ingestion | "Score events come from an API" | No discussion of where the data originates or validation | "Data comes from optical tracking and operators at the stadium, validated by a data provider" |
| Single-tier fan-out | "WebSocket server pushes to all clients" | One server cannot push to 10M clients | "Edge servers at PoPs handle fan-out. Origin publishes once, edge pushes to local clients" |
| WebSocket only | "Use WebSockets for everything" | 5-10% of clients cannot maintain persistent connections | "WebSocket primary, SSE secondary, CDN-cached polling as universal fallback" |
| No CDN for polling | "Polling hits the backend API" | 10M clients polling every 2 seconds is 5M req/s | "Polling hits the CDN, which caches the response with 1-2s TTL. Backend never sees polling traffic" |
| Ignore score corrections | "Just push the score" | VAR can overturn goals 3 minutes later | "Events include sequence numbers and support corrections. Client handles undo events gracefully" |
How I Would Communicate This in an Interview
Here is how I would actually say this:
"I think of this as three stages: ingestion, processing, and fan-out.
At the stadium, data comes from optical tracking systems like Hawk-Eye (sub-50ms latency) and human operators (1-3 seconds). A data provider like Sportradar aggregates these, validates events, and publishes a normalized feed. I consume this feed at my ingestion gateway, which deduplicates events from multiple sources and validates score transitions.
The processing layer enriches the event (add match minute, scorer name, statistics), then publishes to a pub/sub system (Redis Pub/Sub or Kafka) on a topic per match.
The fan-out layer is where it gets interesting. I cannot push one event to 10 million clients from a single server. Instead, I deploy edge servers at 20+ points of presence globally. Each edge server handles about 50,000 WebSocket connections. The edge servers subscribe to pub/sub topics for the matches their clients are watching. When a score event is published, each edge server receives it and pushes to its local clients. Total fan-out: one publish becomes 200 receives and 10 million client pushes. Total latency is about 100-200ms.
For clients that cannot maintain WebSocket connections, I implement a three-tier fallback: WebSocket to SSE to CDN-cached polling. The polling endpoint is cached with a 1-2 second TTL at the CDN, so the backend never sees polling traffic regardless of how many clients are polling.
The hardest part is not the WebSocket protocol. It is the edge fan-out that keeps origin load constant regardless of viewer count."
Notice how I structured that in three clear parts with concrete numbers (50ms, 50K connections, 200 servers). Interviewers remember numbers. "Sub-second" is vague. "200ms from origin to 10 million clients via 200 edge servers" is memorable and demonstrates that you have done the math.
Interview Cheat Sheet
- Hear "real-time sports scores" β say "three stages: stadium data ingestion, event processing with validation, edge-based fan-out to millions of clients"
- Hear "how do updates reach the user so fast" β say "optical tracking at the stadium detects events in 50ms. Edge servers push via WebSocket in 100-200ms. Total end-to-end: under 1 second"
- Hear "how do you handle 10 million viewers" β say "edge servers at 20+ PoPs, 50K connections each. Origin publishes once, edge handles fan-out. Origin load is constant regardless of viewer count"
- Hear "WebSocket vs SSE vs polling" β say "WebSocket for real-time bidirectional (not needed here). SSE for server-push with auto-reconnect. Polling as CDN-cached universal fallback. Use all three in a progressive fallback"
- Hear "what if the WebSocket drops" β say "jittered reconnect with exponential backoff. Fetch current state from CDN on reconnect. Even active WebSocket clients poll every 30s as a consistency check"
- Hear "where does the data come from" β say "optical tracking systems like Hawk-Eye, plus human operators, aggregated by data providers like Sportradar. Multi-source validation before publishing"
- Hear "what about wrong scores" β say "events have sequence numbers. VAR corrections are published as explicit undo events. Client handles score reversals gracefully"
- Hear "CDN for real-time?" β say "CDN with 1-2s TTL serves polling fallback clients. Not truly real-time, but handles 5-10% of clients who cannot maintain persistent connections. CDN absorbs all polling load"
- Hear "cost of this system" β say "200 edge servers at ~$100/month each is $20K/month. Data feed licensing is the real cost: $100K-500K/year depending on league coverage"
- Hear "what about thousands of matches" β say "topic-per-match pub/sub. Edge servers subscribe only to topics their clients watch. Hot matches get more edge capacity, cold matches share servers efficiently"
Test Your Understanding
Quick Recap
- Live sports scores flow through three stages: stadium data ingestion, event processing and validation, and edge-based fan-out to millions of clients.
- Data originates from optical tracking (sub-50ms) and human operators (1-3 seconds) at the stadium, aggregated by commercial data providers like Sportradar.
- Kafka or Redis Pub/Sub provides the event distribution backbone, with topic-per-match routing to keep subscription overhead low.
- Edge servers at 20+ PoPs handle the fan-out: 50K WebSocket connections per server, 200 servers for 10 million viewers.
- Origin server load is constant regardless of viewer count because the edge layer handles all client connections and push delivery.
- Progressive fallback (WebSocket to SSE to CDN-cached polling) ensures all clients get updates regardless of network quality or firewall restrictions.
- Score corrections (VAR overturns) are published as explicit undo events with sequence numbers, never by mutating existing events in the stream.
- Pre-provision for predictable peaks (major events like World Cup finals) and use CDN polling as the safety net for unpredictable surges.
Related Concepts
- WebSockets and Server-Sent Events: Understanding the protocol mechanics, upgrade handshake, and auto-reconnect behavior is essential for implementing the client-side transport layer.
- Edge Computing and CDN Architecture: The fan-out architecture relies on edge PoPs. Understanding CDN topology, anycast routing, and cache TTL behavior explains why CDN-cached polling works at scale.
- Pub/Sub Messaging Patterns: The event distribution layer uses pub/sub with topic-per-match routing. Understanding fan-out, topic management, and consumer groups explains the edge subscription model.
- Real-Time Data Pipelines: The ingestion and processing stages share patterns with event-driven architectures, stream processing, and CQRS. Any system that ingests external events, validates them, and distributes to consumers follows a similar pattern.
- Graceful Degradation Patterns: The three-tier fallback strategy (WebSocket to SSE to polling) applies to any real-time system that must serve clients with varying network quality and client capabilities. This same pattern appears in live stock tickers, collaborative editors, and notification systems.