Matchmaking System#
Problem statement (interviewer prompt)
Design a matchmaking system (chess.com / Dota / Apex): players queue, the system pairs them by skill rating, latency / region, and recent history. Tune for short queue times + balanced matches; handle parties; explain ELO / Glicko / TrueSkill choices.
flowchart LR
P[Player]
Q[[Match Queue]]
MM[Matchmaker<br/>skill / latency]
GS[Game Server]
P --> Q --> MM --> GS
classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
class P,MM,GS service;
class Q queue;
flowchart TB
subgraph Client
PLR[Player UI]
end
subgraph Q[Queue]
QUE[[Per-mode queue]]
REGION[[Region queue split]]
SOLO[Solo / party]
PARTY[Party manager]
end
subgraph Mm[Matchmaker]
SKILL[Skill rating - Elo / Glicko / TrueSkill]
LAT[Latency estimation]
WAIT[Wait-time relaxation]
BAL[Team balance + role]
POLICY[Fairness policies]
end
subgraph Alloc[Server allocation]
SVR[Server pool]
AUTO[Autoscale by demand]
HEALTH[Health checks]
SELECT[Region-aware selection]
end
subgraph Post
LDB[Leaderboards]
HIST[Match history]
REW[Rewards / ranks]
PEN[Penalties / quit early]
end
Client --> Q --> Mm --> Alloc --> GS[Game Server]
Mm --> Post
classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
class PLR,SOLO,PARTY,SKILL,LAT,WAIT,BAL,POLICY,SVR,AUTO,HEALTH,SELECT,LDB,HIST,REW,PEN,GS service;
class QUE,REGION queue;
Skill systems#
- Elo: simple, 1v1 well-suited.
- Glicko / Glicko-2: adds uncertainty.
- TrueSkill: team-aware (Microsoft).
Match formation#
- Find groups of players where:
- skill within window (window widens with wait time)
- latency to chosen server low
- team-balanced and role-balanced
- Optimize as constraint satisfaction; greedy works for most.
Glossary & fundamentals#
| Concept | What it is | Fundamentals |
|---|---|---|
| Pub/Sub | match events | pub-sub-pattern |
| Sharding | per-region queues | database-sharding |
| Distributed lock | server allocation singleton | distributed-lock |
| Resilience patterns | retry, party reform | resilience-patterns |
| Observability | queue depth, time-to-match | observability |
Quick reference#
Functional#
- Pair / group players for matches.
- Skill, latency, party size considered.
- Wait-time relaxation.
- Penalties for quits.
Non-functional#
- Time-to-match < 60 s typical.
- Fair team balance.
- Region-aware to keep RTT low.
Trade-offs#
- Strict skill window = fair but slow; wide = fast but mismatched.
- Solo vs party queues kept separate to avoid stomping.
- Smurf detection = quality lever.
Refs#
- Microsoft TrueSkill paper.
- Riot / Blizzard / Activision engineering posts.
- ByteByteGo "Design matchmaking".
FAQ#
How does a matchmaking system work?#
Players enter a queue tagged with skill rating, region, and party size. A matcher periodically pulls candidates, scores possible pairings, and forms matches when score and queue-time thresholds align.
ELO vs Glicko vs TrueSkill?#
ELO is simple and works for 1v1. Glicko adds rating uncertainty so inactive players widen their search. TrueSkill handles team games by modeling each player's skill as a Gaussian.
How do you balance queue time and match quality?#
Start with a tight skill window. Widen it linearly with time waited so impatient players still match, accepting slightly less balanced games over a long wait.
How does latency influence matchmaking?#
Group players by nearest data center first, then match within region. If queues are thin, expand to neighboring regions with a latency penalty in the scoring function.
How do you scale matchmaking to 1M concurrent players?#
Shard the queue by region and skill band so each matcher sees a manageable slice. Use in-memory data structures with periodic snapshots to disk for crash recovery.