Game Server Development Series — Part 6: Databases & Persistence
Leeting Yan
Modern online games need to store huge amounts of data: player accounts, inventory, currencies, stats, world progress, guild data, match results, analytics—the list is endless.
Unlike single-player games, nothing can be saved locally on the player’s device because it can be modified, hacked, or lost.
This chapter introduces the fundamentals of persistence for game servers, including:
- Player data modeling
- Inventory & economy systems
- Saving and loading data
- Databases for games
- Event-driven persistence
- Preventing lost progress
- Scaling to millions of players
Persistence is one of the most important aspects of running an online game reliably and safely.
1. What Needs to Be Stored?
Different genres store different types of data, but most fall into these categories:
1.1 Player Account Data
- ID
- Username
- Linked platforms
- Authentication tokens
- Ban status
- Last online time
1.2 Character or Profile Data
- Level
- Experience
- Stats and attributes
- Skills / talent trees
- Cosmetics / skins
1.3 Inventory & Items
- Items owned
- Item quantities
- Durability
- Rarity
- Equipment slots
- Currency balances
1.4 Match or Session Data
- Win/loss
- Score
- Damage dealt
- Duration
- MMR/ELO changes
1.5 World Data (MMO / SLG)
- Buildings
- Resources
- Timers
- Worker tasks
- Map ownership
- Guild structures
1.6 Social Data
- Friends
- Blocks
- Guild membership
- Chat logs (partially, not forever)
1.7 Economy Data
- Currency changes
- Purchases
- Marketplace transactions
Games are complex distributed systems; persistence gives them memory.
2. Database Options for Game Servers
Different DB technologies fit different needs.
Most games use multiple databases for different tasks.
2.1 SQL Databases (PostgreSQL, MySQL)
Ideal for:
- Accounts
- Player profiles
- Items
- Transactions
- Long-term, consistent data
Pros
- Strong consistency
- Mature tooling
- Easy migrations
- Easy to query
- Enforces data integrity
Cons
- Harder to scale horizontally
- Not ideal for heavy write bursts
Most games rely heavily on SQL.
2.2 NoSQL Databases (MongoDB, DynamoDB, Cassandra)
Ideal for:
- Large collections of non-relational data
- Flexible schemas
- High write throughput
- Leaderboards
- Session data
Pros
- Easy horizontal scaling
- Flexible schemas
- Very fast for some patterns
Cons
- Weaker consistency (depending on DB)
- Harder to maintain data integrity
Good for huge games with millions of active players.
2.3 In-Memory Stores (Redis, Dragonfly)
Used for:
- Hot data
- Rate limits
- Caching player profiles
- Leaderboards
- Matchmaking pools
- Temporary items
Pros
- Extremely fast
- Great for real-time scenarios
Cons
- Not safe as primary storage
- Requires TTL and careful eviction strategy
Redis acts as the “fast lane” for critical data.
2.4 Event Storage (Kafka, NATS, Pulsar)
Used for:
- Audit logs
- Currency changes
- Player actions
- Match events
- Anti-cheat analysis
Events can be replayed to reconstruct state.
Increasingly common in large MMO and live-ops games.
2.5 Object Storage (S3, GCS, OSS)
Used for:
- Replays
- Large save files
- Chat logs (archived)
- Asset metadata
- Cloud saves for single-player
Cheap, reliable, and great for binary data.
3. Designing a Player Data Model
A good data model is:
- Compact
- Consistent
- Easy to version
- Efficient for common queries
- Resistant to cheating
- Easy to sync during gameplay
Below is a simple example for a player profile + inventory.
3.1 Example Player Model
Players
---------
id (PK)
username
level
exp
gold
gems
last_login
created_at
updated_at
3.2 Example Inventory Model
InventoryItems
--------------
id (PK)
player_id (FK)
item_id
quantity
durability
metadata (JSON)
updated_at
This structure supports:
- Fast lookup of all player items
- Easy modification
- Clear ownership
- Partial updates
3.3 Example Currency Ledger (For Anti-Cheat)
CurrencyHistory
----------------
id
player_id
delta
reason
source
timestamp
This helps detect:
- Fraud
- Duping
- Exploits
- Refund abuse
4. How Data Is Loaded in Real-Time Games
Most real-time servers follow this pattern:
-
Player connects
-
Gateway authenticates
-
Game server loads:
- Profile
- Inventory
- Character data
- Matchmaking rating
-
Data is cached in memory or Redis
-
Game begins
Loading needs to be:
- Fast
- Safe
- Consistent
- Non-blocking
Large games use batched loading, async I/O, or read replicas.
5. How Data Is Saved (Write Strategy)
Game data cannot be saved continuously—too slow and too heavy.
Most games use one of these patterns:
5.1 Save On Important Events
Examples:
- End of match
- Level-up
- Crafting item
- Currency change
- Inventory update
This reduces DB load.
5.2 Periodic Autosave
Every few seconds or minutes:
- MMO world state
- SLG building timers
- Player health/stamina regen
- Daily progression
Autosave must prevent overwriting stale data.
5.3 Write-Behind (Async Queue)
Many games enqueue DB writes:
- Game server records change in memory
- Append to message queue (Kafka, NATS)
- Worker processes commit asynchronously
Benefits:
- Very fast
- Non-blocking
- Resilient to spikes
- Reliable (durable logs)
This is common in large-scale MMO backends.
5.4 Transactional Writes
Used for:
- Purchases
- Currency changes
- Item upgrades
- Crafting
- Guild donations
These must be atomic, so SQL is preferred.
6. Preventing Item Duplication & Money Exploits
Economic stability requires strong consistency.
Common techniques:
6.1 Version Numbers (Optimistic Concurrency)
Each record has a version:
- Load: version = 5
- Save: version = 6
- If another save happened first, reject
Prevents double spending.
6.2 Atomic SQL Updates
UPDATE players SET gold = gold - 100 WHERE id = 42 AND gold >= 100;
Safe against race conditions.
6.3 Currency Ledger + Validation
Every currency change logged → easy detection.
6.4 Server-Only Logic
Never let client propose:
- Final currency values
- Item ownership
- Unlock state
- XP rewards
Only server writes truth.
7. Scaling Persistence to Millions of Players
Large games need:
- Sharding (per region or userID range)
- Read replicas
- Write queues
- Data partitioning
- Redis caching
- Hot/cold data separation
- Daily/weekly cleanup tasks
7.1 Active vs Inactive Players
Store hot data in:
- Redis
- Cache
- In-memory structures
Store cold data in:
- SQL
- NoSQL
- Object storage
This avoids unnecessary load.
8. Saving During Crashes
A game server must handle:
- Crashes
- Network partitions
- Player disconnects
- Abrupt shutdowns
Common techniques:
- Autosave on disconnect
- Periodic autosave
- Write-ahead log (WAL)
- Dedicate match-end save stage
- Server orchestration that drains sessions before shutdown
9. Putting It All Together — A Complete Persistence Flow
Loading
- Player logs in
- Auth verifies token
- Data loaded from DB or Redis
- Cached in server memory
During gameplay
- Mutations are recorded in memory
- Important changes logged immediately
- Low-priority changes queued
Saving
- Player disconnects OR match ends
- Server writes final state
- Ledger updated
- Cache invalidated or refreshed
Backup
- Daily snapshots
- Weekly archives
- Event logs stored in object storage
This provides reliability, security, and performance.
10. Summary
You now understand the foundations of game server persistence:
- What game data must be stored
- How SQL, NoSQL, Redis, and object storage each fit
- How to design player and inventory schemas
- How data is loaded and saved reliably
- How to prevent dupes and exploits
- How to scale to millions of players
- How to maintain consistent and atomic updates
Persistence ensures that your game world remains stable, fair, and trustworthy.