Game Server Architecture
The engineering of shared, real-time simulated state across machines that cannot agree on what time it is. Its whole difficulty is that a game must feel instant while the network is not, so every technique in it is a choice about where to put the error.
Assumes you know: C++ or C# to the point where you can write a loop without a tutorial open, What a game loop is, and what a fixed timestep means, Basic networking - UDP against TCP, latency, jitter, packet loss, Vector arithmetic and enough physics to integrate a position
Overview
What this area actually covers
Two or more machines have to agree, continuously and many times a second, about the position and status of everything in a shared simulated world, while the network between them delivers information late, unevenly, and sometimes not at all. That is the whole subject. Everything with a name in it — tick rates, snapshots, prediction, reconciliation, lockstep, rollback, dead reckoning, lag compensation — is a specific answer to a specific consequence of that one situation.
What makes it a distinct discipline rather than an application of general distributed systems is the deadline. A distributed database can take another fifty milliseconds to reach a correct answer, and usually should. A game cannot: there is a frame going onto a screen in sixteen milliseconds and something has to be drawn in it. So the field is not built around achieving consistency, it is built around choosing which inconsistency the player will notice least. Every technique here is a decision about where to put an error you cannot eliminate — onto the local player's controls, onto the remote player's appearance, onto the bandwidth bill, or onto the person being shot at.
Concretely, the area covers: what the authoritative simulation is and which process owns it; how often that simulation steps and what that rate costs; what goes on the wire and how it is compressed; how a client makes input feel instant when confirmation is a round trip away; how it smooths motion between updates that arrive too rarely to draw directly; how the server resolves an event that a player triggered in a version of the world it has already left behind; and where the trust boundary sits, because in a competitive game the player's own computer is a hostile environment.
There are three things people wrongly bundle in. The first is engine and rendering work: how a scene is drawn, how animation blends, how the material system works. That shares a codebase and almost no reasoning. The second is general backend for games — accounts, stores, leaderboards, telemetry, progression — which is real, large, well-paid work, and is ordinary distributed backend engineering with game-shaped nouns. Playing a match involves both a game server and that backend, and they are entirely different jobs. The third is infrastructure: running fleets of session servers, placing capacity by region, keeping warm pools full. That is closer, and it is usually a platform or SRE specialism rather than netcode.
The boundary worth drawing most carefully is the one against system design. Multiplayer scaling questions — how do you shard a world, how do you allocate servers, how does matchmaking work — sit in system design, and they are asked in system design rounds. What is left, and what this area really is, is the simulation layer: the tick, the state, and the techniques that hide latency inside it. The interesting questions in that layer are not about scale at all. They are about a single client and a single server disagreeing about one entity's position by thirty centimetres, and what you draw.
What sits underneath: state synchronisation
This section has one subsection, and that is honest rather than incomplete. The scaling and matchmaking material lives in system design, the transport and kernel material lives in networking, and what remains is the core: keeping two simulations agreeing well enough, fast enough.
| Subsection | What it is for |
|---|---|
| State Synchronisation | The models and techniques by which two machines running the same world stay close enough to each other for a player not to notice the gap |
State Synchronisation covers three families of technique and the decisions that pick between them. The first is the choice of model. In deterministic lockstep nobody transmits state at all: every machine runs an identical simulation and only inputs go on the wire, so bandwidth is flat regardless of whether the world contains twenty units or two thousand. In an authoritative client-server model one process owns the truth and broadcasts descriptions of it, so bandwidth scales with entities multiplied by observers, but no client can diverge and no client needs to be told what it should not know. The subsection exists partly to make that trade legible, because the axis that decides it is entity count and genre feel, not — as most candidates assume — player count.
The second family is prediction. Because a server-authoritative client must not wait a round trip before your character moves, it applies your input locally and immediately, then reconciles when the server's version of that moment arrives. Doing that correctly requires numbered inputs, a buffer of everything sent but unacknowledged, and a replay step that most people leave out and cannot afford to. Rollback netcode, the technique fighting games are built on, is prediction taken to its logical end: predict the other player's input too, and when the guess proves wrong, restore a saved state and re-simulate every frame since — inside the current frame.
The third family is smoothing. Snapshots arrive far more slowly than frames are drawn, so the client has to invent the positions in between. It can look backwards, buffering snapshots and rendering remote entities slightly in the past so that every drawn position is a genuine blend of two real ones; or it can look forwards, dead-reckoning from the last known position and velocity so nothing is delayed. The first is late but never invented. The second is current but wrong the instant an entity changes direction, and that failure is visible, familiar and impossible to eliminate.
Those three families are best read as one decision tree, because the second and third only arise once the first has been answered.
flowchart TD
A["How many entities must<br/>one client know about?"] -->|"thousands"| B["Deterministic lockstep<br/>inputs only on the wire"]
A -->|"tens"| C["Authoritative server<br/>state on the wire"]
B --> D["Uniform input delay<br/>set by the worst peer"]
C --> E["Predict own input<br/>reconcile on snapshot"]
E --> F["Smooth remote entities<br/>interpolate or dead-reckon"]
D --> G["Optional rollback<br/>to remove that delay"]The branch worth studying is the left one. Lockstep's flat bandwidth is not free — it hands you a uniform input delay and a class of desync bug that is brutal to locate — and rollback exists specifically to buy that delay back on the branch where the entity count is small enough to re-simulate several times in a frame.
What you will find inside are questions that force the trade rather than the definition: when lockstep is the correct answer and what its desync-debugging bill looks like; what a rollback does step by step on one frame and what it costs in CPU and visual coherence; and where interpolation and extrapolation each break, including the way the interpolation delay reappears as a hit-registration bug on the server. Read it as three decisions in sequence — which model, how much do you predict, how do you smooth what is left — because that is the order an interviewer will walk you through it in.
The four mechanisms you have to hold in your head
Almost every question in this area is one of four mechanisms, or an interaction between two of them. Learning them as a set is far more efficient than learning them as a glossary, because each one creates the problem the next one solves.
The tick. The authoritative simulation advances in fixed steps, typically somewhere between twenty and a hundred and twenty-eight times a second. Fixed, because determinism, replay, rewind and stable physics all depend on step 400 being the same step 400 everywhere. The rate is a budget: at sixty ticks a second, one tick is about 16.7 milliseconds of arithmetic — input, physics, combat resolution, and building an outgoing packet for every connected client. Doubling the rate halves that budget and therefore roughly halves how many players one machine hosts, which is why tick rate is a hosting-cost argument dressed up as a fairness argument.
The snapshot. State goes out at its own rate, usually slower than the tick, as a delta against the last snapshot the client has acknowledged receiving. Deltas are why a lossy client costs more bandwidth than a healthy one: while acknowledgements are missing, the server must keep diffing against an older reference, and each successive delta is larger.
Prediction and reconciliation. The client simulates its own input immediately and then corrects itself against the server. This is what makes an authoritative game feel responsive; it is also the source of rubber-banding, and of the requirement that client and server run literally the same movement code.
Interpolation and extrapolation. Other players are drawn either slightly in the past, from buffered snapshots, or slightly in the future, from a projection. Both introduce a specific, nameable error, and choosing per entity type is the skill.
sequenceDiagram
participant C as Client
participant S as Server
C->>C: apply input 45 locally
C->>S: input 45
S->>S: validate then simulate tick
S->>C: snapshot, processed up to 44
C->>C: snap to server state for 44
C->>C: replay 45 onwards
C->>C: draw remote players 100ms lateThe line to look at is the second-to-last one. The client is replaying its own inputs on top of the server's authoritative state, which is why your character does not visibly jump backwards every time a snapshot lands. Remove that replay and prediction stops working entirely — and the last line is a separate delay applied only to other people, which is the asymmetry that makes hit registration hard.
Where it sits in a real system
A running multiplayer match involves at least four distinct systems, and confusing them is the commonest source of a muddled interview answer.
At the front is the platform backend: accounts, entitlements, friends, the store, progression, telemetry. It is HTTP, it is stateless, it scales like any web service, and it is where most engineers at a games company actually work.
Next is matchmaking and allocation. A player queues, a matchmaker forms a roster balanced on skill and latency, and an allocator finds an idle, already-warm server process in a region close to that roster and hands its address to the clients. This is where an important structural fact appears: a game server cannot be stateless, because the simulation is the state and it changes sixty times a second. There is no load balancer spreading requests across a pool, no rolling restart mid-match, and no autoscaling on average CPU. Capacity is planned in whole sessions, held warm because a cold process takes far longer to become playable than a match takes to form, and drained rather than terminated.
Then the match itself: the authoritative simulation, the thing this area is about. It runs for minutes, holds everything in memory, talks UDP to its clients, and is usually thrown away and replaced when the match ends so no state can leak between sessions.
Finally the write-back. Results, currency and progression go to the platform backend, and that hand-off has to be idempotent, because a server that crashes after awarding rewards and before confirming them will be retried.
flowchart TD
A["Client launches<br/>authenticates over HTTPS"] --> B["Platform backend"]
B --> C["Matchmaker forms<br/>a roster"]
C --> D["Allocator picks a warm<br/>server near the roster"]
D --> E["Clients connect over UDP<br/>match simulates"]
E --> F["Results written back<br/>idempotently"]
F --> BThe interesting edge is the change of protocol between the second and third boxes. Everything above the line is request-response over TCP and TLS and behaves like ordinary web infrastructure; everything below it is a continuous bidirectional UDP stream with its own reliability layer. Engineers are usually specialists on one side or the other, and the interview you are in is decided by which side of that line the role sits on.
Who does this work
The narrow specialism is the network programmer or gameplay network engineer. There are not many of them, they are usually in C++, and they sit inside a studio's engine or core gameplay team rather than in a platform group. A day is mostly reading traces: a bug report says players teleport when they leave a vehicle, and the work is reproducing it under injected latency and loss, watching a divergence between predicted and authoritative state, and deciding whether the fix belongs in prediction, in the smoothing, or in what gets replicated at all. There is a great deal of measurement, and comparatively little new architecture, because the architecture was decided years before shipping and is now load-bearing.
The wider role is the gameplay engineer who writes features that happen to be multiplayer. They do not design the netcode, but every ability they write has to be correct under prediction, which means knowing what is authoritative, what is predicted, and what happens when the two disagree. This is where most of the demand for the knowledge on these pages actually is: not in designing a synchronisation model, but in adding a grappling hook to one without introducing a desync.
Around them are the game server platform or live-ops engineers who own fleets, allocation, regional capacity and deployment. That work is closer to SRE than to simulation, and the skills transfer to and from ordinary infrastructure roles. And engine programmers own the replication layer as a framework other teams consume, which is a library-design job with unusually hostile performance constraints.
One distinction is worth making because it changes what you should study. The people who build the synchronisation layer are few and are hired for depth. The people who work correctly within one are many and are hired for competence plus enough understanding to not break it. Most interviews in this area are the second kind, and they are passed by being fluent about mechanisms rather than by having implemented a replication system.
Demand, adoption and how that is changing
This is a genuinely niche specialism, and it is worth being straightforward about why. The number of engineers a studio needs to build a synchronisation layer is small — often one to three people for a whole title — and once it works it is maintained rather than rebuilt. Engine vendors ship replication frameworks that competent teams adopt rather than write, so a large fraction of multiplayer titles never employ anyone to design one. The demand is thin, concentrated in a modest number of studios, and geographically clustered around where those studios are.
Two forces push the other way. Live-service games have made multiplayer the default commercial shape rather than a feature, which has increased the number of engineers who need working fluency even as it has not much increased the number designing the underlying layer. And the technique that used to be exotic is now expected: players have learned the vocabulary, compare netcode between titles publicly, and treat rollback in a fighting game as a requirement rather than a bonus. That has made the knowledge a hiring filter at studios that previously did not test for it, and has moved a lot of it from folklore into things candidates are asked about by name.
What is consolidating is the plumbing. Transport libraries, reliability layers, server fleet management and matchmaking are increasingly bought rather than built, and expecting to be hired to write another reliable-UDP layer is unrealistic. What is not consolidating is the part that touches gameplay, because prediction and smoothing decisions are specific to how a given game feels, and no framework decides for you whether a dash is predicted or whether a projectile is dead-reckoned. That is the durable part of the skill.
The adjacent demand is larger than the direct demand, and it is the honest reason to learn this. Real-time collaborative software, industrial and vehicle simulation, telemetry and remote operation, and financial systems that must act on stale information all reason about the same problem: making a system feel immediate while its information is late. Several of the techniques here — dead reckoning most obviously — came from distributed military simulation before games adopted them, and they travel back out again.
What makes it hard
The conceptual leap is that there is no single present. Each participant is looking at a different moment of the same world, and the differences are not small relative to the events being adjudicated. Once you have accepted that, a whole class of questions changes shape: "was that a hit?" stops having an answer and becomes "whose version of the world do we resolve this in, and who do we make unhappy?" Engineers arriving from ordinary backend work usually try to eliminate the disagreement, and the discipline is about allocating it.
The second difficulty is that the bugs are non-local and often not reproducible. A determinism failure can come from a compiler contracting a multiply and an add on one target and not another, from iteration over a container ordered by memory address, or from a single uninitialised value. It shows up as two machines diverging thousands of ticks later, by which time the cause is far away. The tooling that makes this tractable — per-tick state checksums, full input logs, deterministic replay — has to be built before it is needed, which is a discipline rather than a technique.
The third is that the failure mode is perceptual. There is no assertion for "this feels bad". A correctly implemented system can be unpleasant because the smoothing window is a hundred milliseconds too long, and an incorrect one can feel fine until two players contest the same space. Judging this requires having watched a lot of it under controlled latency, which is precisely the experience that is not substitutable and the reason a small artificial-latency test harness is worth more than any amount of reading.
The fourth is that everything interacts. Raise the send rate and your delta baselines change and bandwidth rises non-linearly. Shorten the interpolation buffer and it starves under jitter, so extrapolation runs more often and corrections become more visible. Extend the server's rewind window and hit registration improves while latency manipulation becomes more profitable to cheat with. There is no dial here that only does one thing, which is why the answer to "just raise the tick rate" is almost always no.
Why study it
Study it if you want to work on multiplayer games and expect to be interviewed on it — in which case this is not optional, it is the round.
Study it if you write anything real-time and shared, even outside games. A collaborative editor, a live dashboard, a control system, a trading interface: all of them face the same problem of presenting something immediate from information that is late, and almost none of them have vocabulary for it as precise as this field's. Knowing that you can render in the past or extrapolate into the future, and that each has a named failure, is directly useful in software that has never heard of a tick rate.
Study it if you want a working mental model of latency. This is the most concrete treatment of latency in software, because the deadline is a screen refresh and the error is visible. Converting a hundred milliseconds into metres of player movement is a habit that makes distributed systems reasoning better in general.
Do not study it as a route into games generally. Most engineering jobs at a games company are platform, tools, backend or gameplay work, and none require this depth. Do not study it as a route into distributed systems either — the overlap in vocabulary is misleading, since consensus, quorums and durable replication barely appear here, and a soft real-time simulation is not a fault-tolerant state machine. And do not study it hoping to be hired to design a replication layer, because those roles are few and go to people who have already shipped one. The realistic outcome is fluency: being the engineer on a multiplayer team who can say why the feature desyncs.
Your first hour
Build the smallest thing that shows you the problem. One hour is enough, and the artefact at the end is a screen on which you can see latency.
Write two processes in whatever language you are fastest in. One is authoritative: a fixed-step loop at sixty steps a second holding a single circle's position, accepting movement input and integrating it. The other is a client that sends input and draws what it is told. Put them on the same machine over UDP.
Then add the only thing that matters: an artificial delay on both directions, adjustable at runtime from zero to five hundred milliseconds, plus a percentage of packets you drop on the floor. Everything you need to understand is on the other side of that slider.
Now do these four things in order and watch each one.
1. no prediction move at 0ms -> fine
move at 200ms -> input feels broken
2. add prediction apply input locally at once
move at 200ms -> instant, but the circle
drifts from the server's version
3. add reconciliation number your inputs, keep the unacknowledged
ones, snap to server state and replay them
-> correct and instant
now DELETE the replay step and watch the
circle jump backwards on every snapshot
4. add a second entity draw it by interpolating buffered snapshots,
then switch to extrapolating from velocity,
and reverse its direction sharply
-> extrapolation visibly overshoots
Step 3's deletion is the exercise. The backwards jump you see is exactly the bug that most descriptions of client-side prediction omit, and having watched it means you will never describe reconciliation as "the client accepts the server's state" again. Step 4 is the second one worth doing slowly: reverse direction at speed and you will see the extrapolated entity continue for the length of your artificial delay before snapping back, which is the failure mode of dead reckoning in one gesture.
If you have a second hour, read Valve's networking documentation with your harness open and map each thing it describes onto what you have just built. It is the most useful primary source in the area precisely because it describes decisions with their costs attached.
What this is not
It is not distributed systems theory. Consensus, quorums, linearisability and durable replication are the vocabulary of a different problem, and importing them here produces answers that are correct and useless: nothing in a match will wait for a quorum, because the frame is going out regardless. The one place they meet is persistence, which is ordinary backend work.
It is not networking in the low-level sense either, though it is adjacent. Kernel bypass, zero-copy receive paths and NIC queue tuning matter at the scale where one process handles enormous packet rates, and that is a systems specialism with its own interview. Game server engineering is a layer above: it decides what goes in the packet and when, not how the packet reaches user space.
It is not the same as being good at games, and it is not mostly maths. The arithmetic involved is division and vector addition. What it demands is the discipline to keep a simulation reproducible and the patience to watch the same second of play a hundred times under different injected latencies.
It is not general games backend, which is the confusion that costs candidates most often. Turning up to a network programmer interview with experience in leaderboards, stores and telemetry is turning up to the wrong interview; the two share an employer and nothing else.
And it is not a solved problem with a correct answer to look up. Every published approach is a different allocation of the same unavoidable error, and the shipped choices differ by genre because the genres disagree about what a player will forgive. An answer that names a technique without naming which error it moved and onto whom has missed the entire point of the field.
There is no single present in a multiplayer game. Every technique in this area is a decision about who experiences the disagreement, and an engineer who can say which one they chose and why is doing the job.
Where to go next
Now practise it
3 interview questions in Game Server Architecture, each with the rubric the interviewer is scoring against.
- How do you make a remote player move smoothly between server updates, and where does that smoothing visibly break?
- When would you choose deterministic lockstep over an authoritative server, and what does each model cost you?
- Walk me through what rollback netcode does on a single frame, and what it costs to run it.