Skip to content

Examples/Gaming

Multiplayer game backend (example)

Ten-player matches with skill-based matchmaking, authoritative game servers from a fleet, and ratings and leaderboards in Postgres and Redis. Clients send inputs over UDP; the server runs the simulation.

Scale: 60k concurrent players, 6k matches running, 30 ticks/s per match

1234567891011121314CLIENTGame clientSERVICELobbyDATABASEPostgresSERVICEMatchmakerCACHEMatchmakingqueueSERVICEAllocatorSERVICEGame serverQUEUEResults queueWORKERStats workerCACHELeaderboardOBJECT STOREReplay storageWORKERAnticheat worker

Select a component to see what it is responsible for and which state it owns.

  1. 1Game client → Lobby: Log in
  2. 2Lobby → Postgres: Load profile
  3. 3Game client → Matchmaker: Join queue
  4. 4Matchmaker → Matchmaking queue: Queue player
  5. 5Matchmaker → Allocator: Allocate server
  6. 6Matchmaker → Game client: Match found
  7. 7Game client → Game server: Inputs and snapshots (UDP)
  8. 8Game server → Results queue: Report result
  9. 9Game server → Replay storage: Upload replay
  10. 10Stats worker → Results queue: Consume results
  11. 11Stats worker → Postgres: Update ratings
  12. 12Stats worker → Leaderboard: Update leaderboard
  13. 13Anticheat worker → Results queue: Consume for analysis
  14. 14Lobby → Leaderboard: Read leaderboard
  • Request / response
  • Server push
  • Bulk data
  • Asynchronous

Select a part to trace its flows.

  • Request / response
  • Server push
  • Bulk data
  • Asynchronous

Parts 12

Flows 14

  1. 1Game client → LobbyLog inRequest / response
  2. 2Lobby → PostgresLoad profileRequest / response
  3. 3Game client → MatchmakerJoin queueRequest / response
  4. 4Matchmaker → Matchmaking queueQueue playerRequest / response
  5. 5Matchmaker → AllocatorAllocate serverRequest / response
  6. 6Matchmaker → Game clientMatch foundServer push
  7. 7Game client → Game serverInputs and snapshots (UDP)Bulk data
  8. 8Game server → Results queueReport resultAsynchronous
  9. 9Game server → Replay storageUpload replayBulk data
  10. 10Stats worker → Results queueConsume resultsRequest / response
  11. 11Stats worker → PostgresUpdate ratingsRequest / response
  12. 12Stats worker → LeaderboardUpdate leaderboardRequest / response
  13. 13Anticheat worker → Results queueConsume for analysisRequest / response
  14. 14Lobby → LeaderboardRead leaderboardRequest / response

Invariants 3

  • Clients cannot set game state

    Clients send inputs only; the server validates and simulates; snapshots carry tick numbers.

    Kept by

  • A match result is applied once

    match_history primary key match_id; the rating update is in the same transaction.

    Kept by

  • A player is in at most one match

    Players are removed from the queue in one Lua script that fails if any is missing; profile status changes with a conditional update.

    Kept by