Creo applicazioni web moderne e strumenti digitali personalizzati per aiutare le attività a crescere attraverso l'innovazione tecnologica. La mia passione è unire informatica ed economia per generare valore reale.
La mia passione per l'informatica è nata tra i banchi dell'Istituto Tecnico Commerciale di Maglie, dove ho scoperto il potere della programmazione e il fascino di creare soluzioni digitali. Fin da subito, ho capito che l'informatica non era solo codice, ma uno strumento straordinario per trasformare idee in realtà.
Durante gli studi superiori in Sistemi Informativi Aziendali, ho iniziato a intrecciare informatica ed economia, comprendendo come la tecnologia possa essere il motore della crescita per qualsiasi attività. Questa visione mi ha accompagnato all'Università degli Studi di Bari, dove ho conseguito la Laurea in Informatica, approfondendo le mie competenze tecniche e la mia passione per lo sviluppo software.
Oggi metto questa esperienza al servizio di imprese, professionisti e startup, creando soluzioni digitali su misura che automatizzano processi, ottimizzano risorse e aprono nuove opportunità di business. Perché la vera innovazione inizia quando la tecnologia incontra le esigenze reali delle persone.
Le Mie Competenze
Analisi Dati & Modelli Previsionali
Trasformo i dati in insights strategici con analisi approfondite e modelli predittivi per decisioni informate
Automazione Processi
Creo strumenti personalizzati che automatizzano operazioni ripetitive e liberano tempo per attività a valore aggiunto
Sistemi Custom
Sviluppo sistemi software su misura, dalle integrazioni tra piattaforme alle dashboard personalizzate
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
🚀
Democratizzare la Tecnologia
La mia missione è rendere l'informatica accessibile a tutti: dalle piccole imprese locali alle startup innovative, fino ai professionisti che vogliono digitalizzare la propria attività. Ogni realtà merita di sfruttare le potenzialità del digitale.
💡
Unire Informatica ed Economia
Non è solo questione di scrivere codice: è capire come la tecnologia possa generare valore reale. Intrecciando competenze informatiche e visione economica, aiuto le attività a crescere, ottimizzare processi e raggiungere nuovi traguardi di efficienza e redditività.
🎯
Creare Soluzioni su Misura
Ogni attività è unica, e così devono esserlo le soluzioni. Sviluppo strumenti personalizzati che rispondono alle esigenze specifiche di ciascun cliente, automatizzando processi ripetitivi e liberando tempo per ciò che conta davvero: far crescere il business.
Trasforma la Tua Attività con la Tecnologia
Che tu gestisca un negozio, uno studio professionale o un'azienda, posso aiutarti a sfruttare le potenzialità dell'informatica per lavorare meglio, più velocemente e in modo più intelligente.
Il mio percorso accademico e le tecnologie che padroneggio
Certificazioni Professionali
8 certificazioni conseguite
Nuovo
Visualizza
Reinvention With Agentic AI Learning Program
Anthropic
Dicembre 2024
Nuovo
Visualizza
Agentic AI Fluency
Anthropic
Dicembre 2024
Nuovo
Visualizza
AI Fluency for Students
Anthropic
Dicembre 2024
Nuovo
Visualizza
AI Fluency: Framework and Foundations
Anthropic
Dicembre 2024
Nuovo
Visualizza
Claude with the Anthropic API
Anthropic
Dicembre 2024
Visualizza
Master SQL
RoadMap.sh
Novembre 2024
Visualizza
Oracle Certified Foundations Associate
Oracle
Ottobre 2024
Visualizza
People Leadership Credential
Connect
Settembre 2024
💻 Linguaggi & Tecnologie
☕Java
🐍Python
📜JavaScript
🅰️Angular
⚛️React
🔷TypeScript
🗄️SQL
🐘PHP
🎨CSS/SCSS
🔧Node.js
🐳Docker
🌿Git
💼
12/2024 - Presente
Custom Software Engineering Analyst
Accenture
Bari, Puglia, Italia · Ibrida
Analisi e sviluppo di sistemi informatici attraverso l'utilizzo di Java e Quarkus in Health and Public Sector. Formazione continua su tecnologie moderne per la creazione di soluzioni software personalizzate ed efficienti e sugli agenti.
💼
06/2022 - 12/2024
Analista software e Back End Developer Associate Consultant
Links Management and Technology SpA
Esperienza nell'analisi di sistemi software as-is e flussi ETL utilizzando PowerCenter. Formazione completata su Spring Boot per lo sviluppo di applicazioni backend moderne e scalabili. Sviluppatore Backend specializzato in Spring Boot, con esperienza in progettazione di database, analisi, sviluppo e testing dei task assegnati.
💼
02/2021 - 10/2021
Programmatore software
Adesso.it (prima era WebScience srl)
Esperienza nell'analisi AS-IS e TO-BE, evoluzioni SEO ed evoluzioni website per migliorare le performance e l'engagement degli utenti.
🎓
2018 - 2025
Laurea in Informatica
Università degli Studi di Bari Aldo Moro
Bachelor's degree in Computer Science, focusing on software engineering, algorithms, and modern development practices.
📚
2013 - 2018
Diploma - Sistemi Informativi Aziendali
Istituto Tecnico Commerciale di Maglie
Technical diploma specializing in Business Information Systems, combining IT knowledge with business management.
Contattami
Hai un progetto in mente? Parliamone! Compila il form qui sotto e ti risponderò al più presto.
* Campi obbligatori. I tuoi dati saranno utilizzati solo per rispondere alla tua richiesta.
What Makes a Game Backend Different from Everything Else
If you have ever built a backend for a web application, you know how it works: a client sends an
HTTP request, the server processes it, queries a database, and returns a JSON response. The cycle
repeats with each interaction. A few extra milliseconds of latency? The user barely notices.
A multiplayer game backend lives in an entirely different universe. Here we are not
talking about requests and responses: we are talking about a continuous bidirectional stream
of data, where every millisecond matters, where hundreds of players share a common state that changes
dozens of times per second, and where a 100ms delay can mean the difference between victory and defeat.
In this first article of the Game Backend Engineering series, we will explore the
complete anatomy of a multiplayer game backend: from network architecture to communication protocols,
from the server-side game loop to message serialization, through scaling strategies and
Backend-as-a-Service platforms. By the end you will have a complete mental map of every component
and the architectural decisions you will need to make.
Series Overview
#
Article
Focus
1
You are here - Anatomy of a Game Backend
Architecture, protocols, components
2
State Synchronization
Netcode, interpolation, prediction
3
Matchmaking Engine
ELO algorithms, queues, lobbies
4
Dedicated Game Servers
Infrastructure and orchestration
5
Anti-Cheat Architecture
Server-side validation, detection
6
LiveOps and Monetization
In-game economy, live events
7
Telemetry and Analytics
Metrics, data pipelines, dashboards
8
Observability
Logging, tracing, alerting
9
Cloud Gaming Infrastructure
Streaming, edge computing, latency
10
Open Source Game Stacks
Nakama, Colyseus, Agones
What You Will Learn
The fundamental differences between a web backend and a game backend
Network models: client-server, peer-to-peer, and relay
How the server-side game loop works (authoritative server)
Communication protocols: TCP vs UDP vs WebSocket vs WebRTC
1. Web Backend vs Game Backend: Two Different Worlds
To understand why a game backend requires a radically different approach, let us compare the
fundamental requirements with those of a traditional web application.
Requirements Comparison: Web vs Game
Aspect
Web Backend
Multiplayer Game Backend
Communication model
Request-response (HTTP)
Continuous bidirectional streaming
Acceptable latency
200-500ms
16-50ms (one frame at 60fps = 16.6ms)
Update frequency
On-demand (click, submit)
20-128 times per second (tick rate)
State
Stateless (each request independent)
Stateful (shared state in memory)
Consistency
Eventual consistency acceptable
Strong consistency in real-time
Scalability
Horizontal (load balancer + replicas)
Vertical per session + horizontal across sessions
Data loss tolerance
Zero (every transaction matters)
Selective (lost positions OK, lost purchases not)
Session duration
Minutes (browsing)
Hours (gaming session)
Bandwidth per user
Sporadic KBs
5-50 KB/s continuous
The critical point is the stateful nature of the game backend. A web server can be
replaced at any time: just redirect traffic to another instance. A game server holds in memory the
state of an active match: player positions, projectiles in flight, active effects, the scoreboard.
If that server crashes, the match is lost.
The Latency Problem in Gaming
In a competitive FPS at 128 tick/s, the server processes an update every 7.8ms.
If a player has 50ms of network latency (RTT), their input reaches the server with a 25ms delay
and the response arrives with another 25ms. The player sees the world with 50ms of delay compared
to the server's reality. At 200ms the game becomes unplayable. This is why techniques like
client-side prediction and lag compensation are fundamental.
2. Network Models: How Players Connect
The first architectural decision concerns the network model: how do clients communicate with each
other and with the server? There are three main approaches, each with specific tradeoffs.
2.1 Client-Server (Authoritative Server)
The dominant model in modern gaming. A central server is the sole authority over
the game state. Clients send their inputs (key presses, mouse movements) to the server, which
validates them, updates the world state, and sends the result to all clients. No client can
directly alter the game state.
Authoritative Client-Server Flow
Client A Server Client B
| | |
|--- Input (W,A) -->| |
| |--- Input (S,D) ---|<
| | |
| [Validate input] |
| [Update state] |
| [Detect collisions] |
| [Calculate result] |
| | |
|<-- World state ----|--- World state -->|
| | |
| [Interpolate/ | [Interpolate/ |
| Predict] | Predict] |
Advantages: maximum security (server controls everything), built-in anti-cheat,
consistent state for all players, easy to debug.
Disadvantages: high infrastructure cost (one server per match), additional latency
(every input must round-trip), single point of failure.
2.2 Peer-to-Peer (P2P)
Every client communicates directly with all others. There is no central server: each player is both
client and "server" for themselves. This model has been popular in fighting games and RTS titles,
where the player count is limited (2-8).
Advantages: no server cost, minimal latency between peers (direct connection),
survives the death of any node.
Disadvantages: impossible to prevent cheats (every client is authority over its
own state), exponential complexity with player count (N*(N-1)/2 connections), NAT traversal issues.
2.3 Relay Server (Server as Proxy)
A compromise between the two models. A central server acts as a relay: it receives
messages from each client and forwards them to all others, but does not process game logic.
The simulation runs on clients; the server is just a "postman."
Network Models Comparison
Characteristic
Client-Server
P2P
Relay
Security
High (server authority)
Low (no authority)
Medium (client-dependent)
Server cost
High
None
Low
Scalability
Hundreds of players
2-8 players
Tens of players
Latency
Medium (round-trip)
Low (direct)
Medium (via server)
Typical use
FPS, MMO, Battle Royale
Fighting, classic RTS
Co-op, casual, mobile
Examples
Valorant, Fortnite, CS2
Street Fighter, StarCraft
Among Us, Fall Guys
3. The Server-Side Game Loop
The heart of an authoritative game backend is the game loop: a cycle that repeats at a
constant frequency (the tick rate), processing inputs, updating state, and sending results
to clients. The tick rate determines the "temporal resolution" of the simulation.
#123;this.TICK_RATE} tick/s`);
setInterval(() => this.tick(), this.TICK_INTERVAL);
}
// Receives input from client (called by network layer)
onPlayerInput(input: PlayerInput): void {
const buffer = this.inputBuffer.get(input.playerId) ?? [];
// Create new array instead of mutating
this.inputBuffer.set(input.playerId, [...buffer, input]);
}
private tick(): void {
const tickStart = performance.now();
this.currentTick++;
// 1. Process all received inputs
const processedInputs = this.processInputs();
// 2. Update game simulation
const updatedState = this.updateSimulation(processedInputs);
// 3. Detect collisions
const stateAfterCollisions = this.detectCollisions(updatedState);
// 4. Update game state (immutable)
this.gameState = {
...stateAfterCollisions,
tick: this.currentTick,
timestamp: Date.now(),
};
// 5. Send updated state to all clients
this.broadcastState(this.gameState);
// 6. Monitor tick performance
const tickDuration = performance.now() - tickStart;
if (tickDuration > this.TICK_INTERVAL) {
console.warn(
`Tick #123;this.currentTick} overrun: #123;tickDuration.toFixed(2)}ms ` +
`(budget: #123;this.TICK_INTERVAL.toFixed(2)}ms)`
);
}
}
private processInputs(): Map<string, PlayerInput> {
const latest = new Map<string, PlayerInput>();
for (const [playerId, inputs] of this.inputBuffer) {
if (inputs.length > 0) {
// Take the last valid input
const lastInput = inputs[inputs.length - 1];
if (this.validateInput(lastInput)) {
latest.set(playerId, lastInput);
}
}
}
// Clear the buffer (new Map, don't mutate)
this.inputBuffer.clear();
return latest;
}
private validateInput(input: PlayerInput): boolean {
// Anti-cheat: verify values are plausible
const maxSpeed = 10;
return (
Math.abs(input.mouseX) <= 360 &&
Math.abs(input.mouseY) <= 90 &&
input.keys.length <= 6
);
}
}
Tick Budget and Overrun
At 64 tick/s, each tick has a budget of 15.6ms. If the tick logic (physics,
collisions, AI, networking) takes more time, the server accumulates delay and players
perceive lag. Monitoring the tick budget is fundamental: in production you track the
p99 of tick duration, not the average.
4. State Management: The Three Layers of State
The state of a multiplayer game is not a monolithic blob: it is divided into layers with different
characteristics and requirements. Each layer requires different storage, synchronization, and
persistence strategies.
The separation into layers is fundamental for performance. The frame state must be
as compact as possible because it is serialized and sent to all clients every tick. The
session state is sent only on change. The persistent state
is never broadcast: only the owner can request it, and it is saved asynchronously to the database.
5. Communication Protocols: TCP, UDP, WebSocket, WebRTC
The choice of transport protocol is one of the most impactful decisions in game backend architecture.
Each protocol offers different tradeoffs between reliability, latency, and complexity.
5.1 TCP (Transmission Control Protocol)
TCP guarantees ordered and reliable delivery of every packet. If a packet is lost, TCP retransmits
it and blocks delivery of subsequent packets until the lost one arrives. This phenomenon is called
head-of-line blocking and is the mortal enemy of real-time gaming.
5.2 UDP (User Datagram Protocol)
UDP is "fire and forget": it sends packets with no guarantees of delivery, ordering, or integrity.
If a packet is lost, it is not retransmitted. This sounds terrible, but for a real-time game it is
exactly what you need: a player's position from 100ms ago is irrelevant if you have the one from
16ms ago.
5.3 WebSocket
WebSocket operates over TCP but provides a bidirectional full-duplex connection. It is the standard
protocol for browser-based and mobile games, where native UDP is not available. Latency is higher
compared to raw UDP, but the ease of implementation and universal compatibility make it the
pragmatic choice for many genres.
5.4 WebRTC (DataChannel)
WebRTC DataChannel offers peer-to-peer (or client-server) communication based on SCTP over UDP.
It supports both reliable and unreliable modes, configurable per channel. It is the only option for
achieving UDP-like communication in the browser.
Network Protocol Comparison for Gaming
Aspect
TCP
UDP
WebSocket
WebRTC DC
Transport
TCP
UDP
TCP
SCTP/UDP
Guaranteed delivery
Yes
No
Yes
Configurable
Guaranteed ordering
Yes
No
Yes
Configurable
Head-of-line blocking
Yes
No
Yes
No (unreliable)
Typical latency
High (retransmit)
Minimal
Medium
Low
Browser support
No (direct)
No
Yes
Yes
NAT traversal
Not needed
Problematic
Not needed
Built-in (ICE)
Complexity
Low
High (custom reliability)
Low
High (signaling)
Ideal for
Chat, turns, lobbies
FPS, racing, simulations
Browser games, mobile
Browser FPS, VoIP
WebTransport: The Future?
WebTransport is a new standard based on HTTP/3 (QUIC) that promises to combine
the best of all worlds: multiplexed bidirectional streams, reliable and unreliable modes,
no head-of-line blocking, and native browser access. In 2026, browser support is maturing
(Chrome and Edge support it), but server-side support is still limited. This is the protocol
to watch for the next generation of browser-based games.
5.5 Hybrid Pattern: Multi-Channel
Modern game backends rarely use a single protocol. The most common pattern is
multi-channel: different channels for different data types.
When you send 64 updates per second to 100 players, every extra byte in the message multiplies
6,400 times per second. The choice of serialization format directly impacts bandwidth, latency,
and infrastructure cost.
In a multiplayer game, the network connection is never 100% reliable. Players disconnect due to
unstable WiFi, network switching (4G/WiFi), client crashes, or simply closing the game. A robust
game backend must handle all of this transparently.
7.1 Session Lifecycle
Game Session Lifecycle
[Client initiates connection]
|
v
[Handshake + Authentication] -- JWT token or session ticket
|
v
[Session created on server] -- SessionID, PlayerID, Timestamp
|
v
[Heartbeat loop started] -- Ping every 1-5 seconds
|
v
[Game active] -- Input/State loop
|
v
[Disconnection detected] -- Heartbeat timeout (10-30s)
|
+--- [Reconnection window] -- 30-120s to reconnect
| |
| +--> Reconnected: restore session, send current state
| |
| +--> Timeout: session destroyed, player removed
|
v
[Session terminated] -- Save stats, free resources
7.2 Heartbeat and Disconnect Detection
The heartbeat is a periodic message the client sends to the server (or vice versa)
to signal that the connection is active. If the server receives no heartbeat for a configurable
period, it considers the client disconnected. The heartbeat also serves to measure
latency (RTT) and jitter.
Heartbeat and Reconnection System - TypeScript
interface ConnectionMetrics {
readonly lastHeartbeat: number;
readonly rttMs: number;
readonly jitterMs: number;
readonly packetLoss: number;
readonly rttHistory: ReadonlyArray<number>;
}
class ConnectionManager {
private readonly HEARTBEAT_INTERVAL = 2000; // 2 seconds
private readonly DISCONNECT_TIMEOUT = 15000; // 15 seconds
private readonly RECONNECT_WINDOW = 60000; // 60 seconds
private readonly sessions: Map<string, SessionData> = new Map();
handleHeartbeat(sessionId: string, clientTimestamp: number): void {
const session = this.sessions.get(sessionId);
if (!session) return;
const now = Date.now();
const rtt = now - clientTimestamp;
// Calculate jitter (RTT variation)
const prevRtt = session.metrics.rttMs;
const jitter = Math.abs(rtt - prevRtt);
// Create new metrics object (immutable)
const updatedMetrics: ConnectionMetrics = {
lastHeartbeat: now,
rttMs: rtt,
jitterMs: jitter,
packetLoss: session.metrics.packetLoss,
rttHistory: [...session.metrics.rttHistory.slice(-19), rtt],
};
// Update session with new metrics
this.sessions.set(sessionId, {
...session,
metrics: updatedMetrics,
});
}
checkDisconnections(): void {
const now = Date.now();
for (const [sessionId, session] of this.sessions) {
const elapsed = now - session.metrics.lastHeartbeat;
if (elapsed > this.DISCONNECT_TIMEOUT && session.status === 'connected') {
// Move to "disconnected" status but keep the session
this.sessions.set(sessionId, {
...session,
status: 'disconnected',
disconnectedAt: now,
});
console.log(`Player #123;session.playerId} disconnected. Reconnect window: 60s`);
}
if (session.status === 'disconnected') {
const disconnectElapsed = now - (session.disconnectedAt ?? now);
if (disconnectElapsed > this.RECONNECT_WINDOW) {
// Reconnection window expired
this.destroySession(sessionId);
}
}
}
}
handleReconnect(playerId: string, newSocket: WebSocket): boolean {
// Find disconnected session for this player
for (const [sessionId, session] of this.sessions) {
if (session.playerId === playerId && session.status === 'disconnected') {
// Restore session with the new connection
this.sessions.set(sessionId, {
...session,
status: 'connected',
socket: newSocket,
metrics: { ...session.metrics, lastHeartbeat: Date.now() },
});
// Send current game state to reconnected client
this.sendFullStateSync(sessionId);
return true;
}
}
return false;
}
private destroySession(sessionId: string): void {
const session = this.sessions.get(sessionId);
if (session) {
console.log(`Session #123;sessionId} destroyed for player #123;session.playerId}`);
this.sessions.delete(sessionId);
}
}
}
8. Databases: The Persistence Stack
A game backend does not use a single database: it uses a stack of storage engines,
each optimized for a specific data type and access pattern.
Database Stack for Game Backend
Layer
Technology
What It Stores
Latency
L1 - In-memory
In-RAM data structures
Frame state, input buffer
< 0.001ms
L2 - Distributed cache
Redis / Dragonfly
Session state, leaderboard, matchmaking queue
0.1-1ms
L3 - Relational database
PostgreSQL / CockroachDB
Player profiles, inventory, purchases, ranking
1-10ms
L4 - Time-series
TimescaleDB / InfluxDB
Telemetry, performance metrics, analytics
1-5ms
L5 - Object storage
S3 / GCS
Replays, screenshots, assets, backups
50-200ms
8.1 Redis for Real-Time State
Redis is the most critical component of a game backend's database stack. Its native data structures
(sorted sets, hashes, lists, pub/sub) map directly to gaming patterns:
Sorted Sets for leaderboards and rankings (ZADD, ZRANK, ZRANGE)
Hashes for session state (HSET, HGETALL)
Lists for matchmaking queues (LPUSH, RPOP)
Pub/Sub for communication between game servers and services
Streams for event sourcing and audit logs
8.2 PostgreSQL for Persistence
For all data that must survive server restarts: player profiles, progression, inventory, economic
transactions, match history. PostgreSQL offers ACID transactions, JSON(B) for semi-structured
data, and with extensions like pgvector it also supports similarity searches for
skill-based matchmaking.
Unlike stateless web servers that scale by adding replicas behind a load balancer, game servers
are stateful: each instance manages one or more active matches with in-memory
state. This makes scaling and orchestration much more complex.
9.1 Dedicated Game Servers
A dedicated game server is a process that runs the simulation of a single match
(or a game world area). Unlike "listen servers" (where a player also acts as the server), the
dedicated server runs on dedicated cloud hardware, guaranteeing consistent performance and fairness.
Multi-Layer Game Backend Architecture
[Internet]
|
[CDN / Edge]
|
[Load Balancer (L7)]
/ \
[Gateway API] [Gateway API]
| |
+--------+--------+-------+--------+
| | | | |
[Matchmaker] [Auth] [Social] [Shop] [Leaderboard]
| |
v v
[Fleet Manager / Orchestrator] [Redis Cluster]
| |
+---+---+---+---+ |
| | | | | |
[GS] [GS] [GS] [GS] [GS] <---> [PostgreSQL]
Game Server Instances
Legend:
GS = Game Server (one match each)
Each GS is a container/pod with dedicated CPU and RAM
The Fleet Manager scales GS count based on demand
9.2 Containerization with Docker
Each game server runs in a Docker container, ensuring isolation, reproducibility, and rapid
deployment. The container includes the server binary, configurations, and dependencies.
The lightweight nature of containers allows spinning up new instances in seconds.
9.3 Orchestration with Kubernetes and Agones
Agones is an open-source project by Google that extends Kubernetes to manage
dedicated game servers. It provides Custom Resource Definitions (CRDs) to define GameServer,
Fleet, and FleetAutoscaler resources. The fleet manager monitors match demand and automatically
scales the number of available servers.
Orchestration Platform Comparison
Platform
Type
Cloud
Strengths
Agones
Open-source (K8s)
Any + on-premise
Total flexibility, no vendor lock-in
Amazon GameLift
Managed (AWS)
AWS
AWS integration, FlexMatch matchmaking
Azure PlayFab
Managed (Azure)
Azure
Complete ecosystem (LiveOps, analytics, economy)
Google Cloud Game Servers
Managed (GCP)
GCP
Based on Agones, global scaling
10. Scaling Patterns: Lobby, World, Zone
Not all games scale the same way. The scaling pattern depends on the genre and structure of the
game. Here are the three main patterns.
10.1 Lobby/Match Server
Used by FPS, Battle Royale, and MOBA games. Each match is an isolated instance with a fixed
number of players (10-100). When the match ends, the server is destroyed and resources recycled.
Scaling = increasing the number of instances.
10.2 World Server (Persistent World)
Used by MMOs. A persistent world is divided into zones, each managed by a
dedicated server. Players move between zones with a transparent handoff. Zone servers
communicate with each other to manage boundaries.
10.3 Instanced Zones
A hybrid: the world is persistent, but specific areas (dungeons, raids, arenas) are dynamically
instanced. Each player group receives their own copy of the area. This allows
scaling high-density areas without overloading the world server.
Visual Scaling Patterns
LOBBY/MATCH SERVER (FPS, BR):
[Matchmaker] --> [Server Pool]
|
+---------+---------+
| | |
[Match 1] [Match 2] [Match 3]
10 players 10 players 10 players
(30 min) (25 min) (new)
WORLD SERVER (MMO):
[World Manager]
|
+---+---+---+---+
| | | | |
[Zone A][Zone B][Zone C][Zone D]
City Forest Dungeon PvP
200 p. 50 p. 30 p. 80 p.
^ ^
|--- Zone handoff ---|
INSTANCED ZONES (MMO + Dungeon):
[City Zone] --> [Dungeon Entrance]
|
+---------+---------+
| | |
[Dungeon [Dungeon [Dungeon
Copy 1] Copy 2] Copy 3]
5 players 5 players 5 players
11. Backend-as-a-Service for Games: The Platforms
Not everyone needs (or wants) to build a game backend from scratch. Backend-as-a-Service (BaaS)
platforms offer ready-to-use components: matchmaking, leaderboards, authentication, storage,
in-game economy. The choice depends on budget, desired control, and game genre.
Gaming BaaS Platform Comparison
Platform
Server Language
Open Source
Self-Hosted
Strengths
Ideal For
Nakama
Go, TS, Lua
Yes
Yes
Real-time, matchmaking, storage
Indie, mid-size, mobile
Colyseus
TypeScript
Yes
Yes
Authoritative, automatic state sync
Browser games, prototypes
PlayFab
C# (Azure Functions)
No
No
LiveOps, economy, analytics
AAA, mobile F2P
Amazon GameLift
C++, C#
No
No
Fleet management, FlexMatch
AAA multiplayer
Photon
C#
No
Partial
Unity integration, relay
Unity games, mobile
Mirror
C#
Yes
Yes
Unity networking, HLAPI replacement
Unity indie games
Build vs Buy: Decision Criteria
Use a BaaS if: limited budget, time-to-market priority, standard genre (casual, puzzle, card game), small team
Build custom if: extreme latency requirements (<20ms), unique game logic, need total control over netcode and anti-cheat, scale >100K CCU
Hybrid approach: use a BaaS for authentication, leaderboards, and social, but build a custom game server for game logic
12. Performance Metrics: What to Monitor
A game backend without observability is a ticking time bomb. These are the fundamental metrics
that every team must monitor in production.
Key Game Backend Metrics
Metric
Description
Target
Alert
CCU
Concurrent Connected Users
Genre-dependent
> 90% capacity
Tick Duration (p99)
Tick processing time
< 80% of tick budget
> 90% of budget
RTT (p50 / p95 / p99)
Client-server Round-Trip Time
p50 < 50ms, p99 < 150ms
p99 > 200ms
Packet Loss
Percentage of lost packets
< 1%
> 3%
Jitter
Latency variation
< 10ms
> 30ms
Messages/sec
Messages processed per second per server
> 10K msg/s
< 5K msg/s
Bandwidth per player
Outbound KB/s per player
5-30 KB/s
> 50 KB/s
Reconnection Rate
Percentage of successful reconnections
> 90%
< 70%
Server Startup Time
Time to spin up a new instance
< 10s
> 30s
Example: Tick Metrics in Go
// Tick metrics structure for a game server in Go
type TickMetrics struct {
TickNumber uint64
Duration time.Duration
PlayersActive int
InputsProcessed int
MessagesOut int
BytesOut int64
}
type ServerMetrics struct {
mu sync.RWMutex
tickDurations []time.Duration // ring buffer last 1000 ticks
totalTicks uint64
overrunCount uint64
ccu int32
}
func (m *ServerMetrics) RecordTick(metrics TickMetrics) {
m.mu.Lock()
defer m.mu.Unlock()
idx := m.totalTicks % 1000
m.tickDurations[idx] = metrics.Duration
m.totalTicks++
if metrics.Duration > tickBudget {
m.overrunCount++
log.Printf(
"TICK OVERRUN #%d: tick=%d duration=%v budget=%v players=%d",
m.overrunCount,
metrics.TickNumber,
metrics.Duration,
tickBudget,
metrics.PlayersActive,
)
}
}
// Calculate p99 percentile of tick duration
func (m *ServerMetrics) P99TickDuration() time.Duration {
m.mu.RLock()
defer m.mu.RUnlock()
sorted := make([]time.Duration, len(m.tickDurations))
copy(sorted, m.tickDurations)
sort.Slice(sorted, func(i, j int) bool {
return sorted[i] < sorted[j]
})
idx := int(float64(len(sorted)) * 0.99)
return sorted[idx]
}
13. Putting It All Together: The Complete Architecture
Here is an overview of all the components of a modern multiplayer game backend and how they
interact with each other.
In this article you have gained a comprehensive understanding of the anatomy of a multiplayer
game backend: from network architecture to transport protocols, from the authoritative game loop
to message serialization, from connection management to scaling patterns. You have seen how each
component interacts with the others and which architectural tradeoffs guide design decisions.
In the next article we will dive into the heart of multiplayer netcode:
state synchronization. We will explore in depth client-side prediction,
server reconciliation, interpolation, lag compensation, and rollback netcode. We will see how
modern games create the illusion of a smooth experience despite network latency.
Additional Resources
Gabriel Gambetta: "Fast-Paced Multiplayer" - The definitive article series on client-server architecture for gaming