Design a live sports betting platform handling 100K bets/sec at peak with sub-200ms acceptance latency. Covers event-sourced ledgers, in-memory odds caching, and batch settlement.
Live sports betting is an increasingly popular system design interview topic because it combines real-time data streaming, financial-grade consistency, and extreme traffic spikes into a single problem. The core challenge is accepting bets against continuously changing odds while maintaining an immutable audit trail that satisfies regulatory requirements. Every bet must be validated against the current market price, and the system must reject bets placed against stale odds that have moved beyond a tolerance threshold.
At production scale, platforms like DraftKings and FanDuel process over 100,000 bet placements per second during kickoff spikes for major sporting events. Odds update 10 to 50 times per second per market across 100,000 active markets, generating a firehose of 50,000 odds updates per second from external data feeds like Sportradar. The read path serving market browsers sustains 200,000 requests per second. This extreme concurrency, combined with the requirement for sub-200ms bet acceptance latency, rules out traditional request-response patterns that touch a relational database on every bet.
The problem becomes especially rich when you consider the settlement phase. When a sporting event ends, the system must correctly settle hundreds of thousands of open bets in a batch operation, credit user balances for winning bets, and produce a complete audit record. Settlement must be idempotent to handle retries and must never double-pay or miss a payout. Interviewers also expect candidates to address market suspension (e.g., a VAR review in football that halts all betting for a market), odds staleness windows during propagation delays, and the regulatory requirement for a tamper-proof transaction history.
This template models the complete live betting architecture: external odds feed ingestion, in-memory odds caching for sub-100ms validation, an event-sourced append-only ledger for bets, Kafka-based event streaming for decoupled processing, and an asynchronous batch settlement pipeline triggered on event completion.
The live betting architecture is built around an event-sourced append-only ledger and an in-memory odds cache that together enable sub-200ms bet acceptance at 100K transactions per second. The data flow begins with external odds feeds from providers such as Sportradar and Betgenius. An OddsWorker fleet of 30 instances ingests the raw feed, normalizes it into an internal format, publishes structured odds events to an OddsStream (Kafka with 64 partitions keyed by market_id), and writes directly to an OddsCache (Redis 6-node cluster). This dual-write ensures both durability via Kafka and low-latency reads via Redis.
Bettors interact through an API Gateway that performs JWT authentication and per-user rate limiting, then routes to an Application Load Balancer distributing traffic between two independent services. OddsService (15 pods) handles the read-heavy path, serving market odds and user balances from Redis cache in approximately 2ms per request, sustaining 300K reads per second. BetService (20 pods) handles the write-heavy path: it validates each bet by comparing the submitted odds against the current cached odds (rejecting if the market has moved beyond tolerance), atomically debits the user balance in Redis, writes an immutable bet record to the LedgerDB (DynamoDB in append-only mode with 64 partitions), and publishes a bet-placed event to BetStream (Kafka).
The append-only ledger is the architectural cornerstone. No UPDATE operations are ever performed; every state change (placement, cancellation, settlement) is a new INSERT. This creates a complete regulatory audit trail that can be replayed to reconstruct state at any point in time. When a sporting event completes, SettlementWorker instances (20 workers) consume bet events from BetStream, read all open bets for the event from LedgerDB via a secondary index on event_id, compute outcomes in memory, credit winning balances, and write settlement records back to the ledger. Settlement is sharded by event_id so multiple events settle in parallel, processing 500K bets per event in approximately 30 seconds.
Choice
Event-sourced append-only ledger on DynamoDB
Rationale
Betting is a regulated financial domain where every transaction must be auditable. An append-only ledger that never performs UPDATE operations creates a complete, tamper-evident audit trail. If a settlement bug is discovered, the entire bet history can be replayed to reconstruct correct state. This is the industry standard used by DraftKings, FanDuel, and other licensed sportsbooks.
Choice
In-memory Redis cache with sub-5ms reads
Rationale
At 100K bets per second, each bet must check current odds before acceptance. A database read at 10-15ms per bet would require over a million concurrent database connections and add unacceptable latency. Redis returns odds in approximately 2ms and handles over a million operations per second on a single node. The cache is updated by OddsWorker within milliseconds of feed changes, keeping the staleness window under 500ms.
Choice
Separate OddsService (read-heavy) and BetService (write-heavy)
Rationale
OddsService handles 200K reads per second with simple cache lookups, while BetService handles 100K writes per second with complex validation, balance debit, database write, and Kafka publish. Separating them enables independent scaling: 15 read pods versus 20 write pods. Their failure modes also differ significantly. Odds reads can tolerate briefly stale cached data, but bet writes require strong consistency to prevent double-betting.
Choice
Batch settlement per event with Kafka-driven trigger
Rationale
A single Premier League match may accumulate 500,000 open bets. Processing them individually through an API would take hours and create enormous database pressure. Batch settlement reads all bets for a completed event in bulk, computes outcomes in memory, and writes results in a single batch operation, settling 500K bets in roughly 30 seconds. Sharding by event_id enables multiple sporting events to settle in parallel without contention.
Target RPS
100K bets/s (peak), 200K odds reads/s
Latency (p99)
<200ms (p99 bet acceptance)
Storage
~2 TB/year (append-only bet ledger)
Availability
99.99%
This template is for educational and illustration purposes only. It may not represent the optimal production design for this problem. Real-world systems involve additional considerations (compliance, specific cloud provider constraints, organizational requirements) not captured here. Use this as a starting point for discussion, not as a production blueprint.
The bet placement request includes the odds the user saw at the time of their decision (odds_at_placement). BetService compares this value against the current odds in the Redis cache. If the market has moved beyond a configurable tolerance threshold (typically 5%), the bet is rejected with a clear error indicating the odds have changed. The user is shown the updated odds and can choose to place the bet at the new price. This odds-tolerance mechanism handles the inherent staleness window between odds propagation and bet submission without requiring distributed locks.
An append-only ledger satisfies three critical requirements in sports betting. First, regulatory compliance mandates a tamper-proof audit trail of every bet lifecycle event. Second, event sourcing enables full state reconstruction by replaying the event log, which is invaluable for debugging settlement disputes. Third, append-only writes to DynamoDB avoid read-modify-write cycles that would create contention at 100K writes per second. Each bet state transition (placed, settled, voided) is a new immutable record, and the current state is derived by reading the latest event for each bet.
When a market is suspended due to an in-game event such as a VAR review in football or a challenge review in tennis, the external odds feed sends a suspension signal. OddsWorker immediately sets a suspended flag in the Redis OddsCache for that market. BetService checks this flag as the first validation step before accepting any bet. Suspended markets reject bet placements instantly with a descriptive error. The suspension is lifted when the odds feed resumes normal updates, and the flag is cleared atomically in Redis.
Settlement uses a two-phase approach for correctness. First, SettlementWorker reads all bets for the completed event from the LedgerDB using a secondary index on event_id. It filters to bets in the PLACED state (excluding already-settled or voided bets). Second, it writes settlement records with a conditional check that the bet has not already been settled, making the operation idempotent. If the worker crashes mid-settlement and restarts, the conditional writes prevent any bet from being settled twice. The append-only ledger provides a complete audit trail for post-settlement verification.
Between an odds update arriving at OddsWorker and reaching the Redis cache, there is a 50 to 500 millisecond window where the cached odds are stale. Bets placed during this window are validated against slightly outdated prices. The odds-tolerance threshold (typically 5% movement) is specifically designed to absorb this staleness. For most markets, odds do not move more than 5% within 500ms unless a significant in-game event occurs, in which case the market is typically suspended. Production sportsbooks accept this small risk as a trade-off for the performance benefit of cache-based validation.
Sign in to join the discussion.
Ready to design your own Live Betting?
Open the simulator, place components on the canvas, wire them up, and run a traffic simulation to see how your architecture performs under real load.
Open Simulator