Gaming & realtime, an interactive architecture walkthrough

Real-time leaderboard: how the architecture works

How a real-time leaderboard ranks millions of players with in-memory sorted sets, takes scores only from game servers, and rolls boards over by season.

This is a learning explainer based on public engineering writing and general design practice. It is simplified, it is not the actual architecture of any company, and it may be inaccurate.

26 components, 25 connections, 12 steps. Updated 4 November 2026.

Interactive diagram

Overview

A real-time leaderboard ranks players by score and answers three questions quickly: who is at the top, what is my exact rank, and who is just above and below me. A sorted set in memory answers each in logarithmic time, so rank is computed live instead of by a nightly batch job. Scores are submitted by authoritative game servers, de-duplicated and checked, and applied through a partitioned event stream.

The sorted set is fast but not the only copy: each player's best score is also kept in a relational database, and boards are rebuilt from it if the in-memory copy is lost. Seasonal and daily boards are separate keys created on a schedule, and closed seasons are archived to object storage. This is a simplified learning design, not any game's production system.

Trade-offs and what changes at scale

One sorted set lives on one Redis shard, which caps the size and write rate of a single board; very large games split boards by region or season, or compute approximate ranks for players far from the top by bucketing scores. Redis replication is asynchronous, so a failover can lose recent updates, which is why the database is the source of truth. Ties need a rule, and packing the tie-break into the score has to stay within the 53 bits a double holds exactly. Caching the top N for a second or two trades a little freshness for a large drop in read load.

How it works, step by step

The walkthrough above, as text. Each step lights up the components named under it.

  1. When a match ends, the Game Server, not the player's device, submits the result through the API Gateway. Scores reported by clients are easy to forge, so only the authoritative server can write.

    Components Game Server, API GatewayVia submit result

  2. The Score Ingest Service verifies the server's signature, drops duplicates by match id and runs the Anti-cheat Checker for impossible values. Retries from the game server then cannot count a match twice.

    Components Score Ingest Service, Anti-cheat CheckerVia POST /scores

  3. Accepted scores go to the Score Events topic, partitioned by leaderboard id so each board's updates are applied in order. A burst at the end of a tournament queues here instead of overloading Redis.

    Components Score EventsVia score accepted

  4. The Leaderboard Workers first upsert each player's best score in the Score DB, updating only if the new score is higher. This durable copy is what a board is rebuilt from if Redis loses data.

    Components Score DB, Leaderboard WorkersVia upsert if higher

  5. The workers then write the score into the board's entry in the Leaderboard Sorted Sets with ZADD GT, which only raises a score and runs in O(log N). Ties are broken by packing the score and an earlier-is-better timestamp into one number that stays within the range a double stores exactly.

    Components Leaderboard Sorted SetsVia ZADD GT

  6. The most requested view, the top 100, is read from the sorted set once and kept in the Top-N Cache for a second or two. Thousands of players opening the board then cost one Redis range query, not thousands.

    Components Top-N Cache, Leaderboard API, API GatewayVia top N

  7. For "my rank", the Leaderboard API calls ZREVRANK on the sorted set and then ZRANGE for the players just above and below. Both are logarithmic, so a player's exact rank among millions is computed live.

    Components Leaderboard APIVia ZREVRANK / ZRANGE

  8. A friends board gets the player's friend ids from the Friends Service, reads their scores from the sorted set and sorts that small list in the API. Names and avatars come from the Profile Service, so the sorted set stores only player ids.

    Components Friends Service, Profile ServiceVia friend ids

  9. The Rank Notifier watches the same score events and pushes a message through the Realtime Gateway when a player enters the top 100 or passes a friend. Pushing only meaningful changes avoids streaming every rank shift to every player.

    Components Rank Notifier, Game Client, Leaderboard Sorted SetsVia push update

  10. The Season Scheduler starts each season or daily board under a new key instead of clearing the old one. Writes switch to the new key at a set time, so there is no moment when the board is empty.

    Components Season SchedulerVia new board key

  11. When a season closes, the Snapshot Worker copies the final standings to the Season Archive and the old key is given an expiry. Prize payouts are then computed from a frozen copy that later writes cannot change.

    Components Snapshot Worker, Season Scheduler, Leaderboard Sorted SetsVia write standings

  12. Score events also load into the Analytics Store for score distributions and cheat review, while Observability tracks ingest lag and Redis memory per board. One very large board lives on a single Redis shard, so its size is watched closely.

    Components Analytics Store, ObservabilityVia load

Sequence diagram

The same walkthrough as a UML sequence diagram, one lane per layer or group (20 components in all), left to right in the order a request reaches them, numbered by step. A loop on a lane is a step that stays inside that group. Solid arrows are synchronous calls, dashed are asynchronous.

Real-time leaderboard: sequence diagram of the walkthroughPlayers & GamesEdgeScore IngestRankingQuerySeasons &RecoveryAnalytics StoreObservabilitysubmit result1POST /scores2check2score accepted3upsert if higher4consume4ZADD GT5top N6GET ranks6ZREVRANK / ZRANGE7friend ids8hydrate players8push update9new rank9WebSocket9new board key10write standings11season closed11read final ranks11load12lag12

Key components

Edgelayer

  • API Gateway: auth, rate limits, routing
  • Realtime Gateway: pushes rank changes (websocket)

Players & Gameslayer

  • Game Client: shows ranks, never reports scores
  • Game Server: authoritative match results

Score Ingestdomain

  • Anti-cheat Checker: flags impossible scores
  • Score Events: partitioned by leaderboard id (kafka)
  • Score Ingest Service: verify signature, de-dup by match id

Rankingdomain

  • Leaderboard Sorted Sets: one sorted set per board (redis)
  • Leaderboard Workers: apply scores to boards
  • Score DB: best score per player per board (postgresql)

Querydomain

  • Friends Service: friend lists for friend boards
  • Leaderboard API: top N, my rank, players around me
  • Profile Service: names, avatars, country
  • Rank Notifier: detects rank changes worth pushing
  • Top-N Cache: top 100 per board, 1-2 s TTL (redis)

Seasons & Recoverydomain

  • Season Archive: frozen final standings (s3)
  • Season Scheduler: opens and closes boards
  • Snapshot Worker: final standings, rebuilds boards

Analytics Store

  • Analytics Store: score distributions, cheat review (clickhouse)

Observability

  • Observability: ingest lag, Redis latency, memory

Sources

Public writing this explainer draws on. Read these for what the real systems actually do.

Make it yours

Copy this diagram and its walkthrough into your own workspace, then change anything: swap Postgres for DynamoDB, add a cache, rewrite the narration. Free, and it uses no AI credits.

This is a learning explainer based on public engineering writing and general design practice. It is simplified, it is not the actual architecture of any company, and it may be inaccurate. Real systems differ in the details. Browse the library.