Cloud Save for Games: DIY Database vs Managed Backend

Player save data looks solved until two devices disagree or a modified client writes its own progress. The five failure modes, and when a managed backend earns it.

Saving player data is the first backend feature almost every game needs and the one most teams underestimate. A single JSON blob keyed by player id works perfectly until the day it does not, and the day it does not is usually launch day. This is a decision guide for when a database you run yourself is genuinely enough, and what a managed backend has to do before it earns the dependency.

What Actually Goes Wrong

The problems below are not exotic. They are the ordinary consequences of a save system that was specified as "store the blob".

1. Two devices, one truth

A player opens the game on a desktop, plays, then opens it on a laptop that still holds yesterday's state. Whichever client writes last wins, and several hours of progress vanish. A last-write-wins blob cannot detect this, because nothing in the write says which version it was based on.

The fix is optimistic concurrency: the client sends the version it read, and the server rejects the write if the stored version has moved on. That turns silent data loss into a conflict your game can actually handle.

2. The client is not trustworthy

If the game client can write its own save, then the save says whatever the client says. For a single-player game that is a choice you can make. For anything with a leaderboard, an economy, or matchmaking, it means the ranking is a ranking of who edited their save.

The boundary that matters is not encryption, which only slows a determined player down. It is which credential is allowed to write. Progression that other players can see should be written by something the player does not control.

3. Retries duplicate work

Mobile networks drop requests after the server has already committed them. If your save write is additive, a retry applies it twice: the currency is granted again, the counter jumps. Idempotent writes and absolute values rather than deltas remove most of this class, and the rest needs an operation id the server can recognise as a repeat.

4. The guest problem

Letting people play before they register is good for conversion and bad for data. The player accumulates hours against an anonymous identity, then signs up, and the naive implementation gives them a fresh empty account. They do not file a bug. They leave.

Guest sessions need to be upgradeable in place, so the account gains an email without changing the identity the save is attached to.

5. The blob grows

Saves start at a few kilobytes and grow with every feature. Eventually every autosave ships the entire inventory over a mobile connection to change one number. Splitting save data by key, and patching a field rather than rewriting the document, is the difference between a save that scales and one that gets slower every patch.

When Rolling Your Own Is The Right Call

  • The game is single-player and the save is genuinely local, with cloud sync as a convenience rather than a source of truth.
  • Nothing in the save affects anything another player sees. No leaderboards, no shared economy, no matchmaking on stats.
  • You already run a backend with an on-call rotation, and adding one more table is marginal.
  • Your data model is unusual enough that a general-purpose document API would fight you.

If that describes you, a table with a version column and a server that refuses client-supplied progression will carry you a long way. The rest of this article is not an argument that you are wrong.

When A Managed Backend Earns It

Need What it has to give you
Conflict detection Versioned writes that fail loudly instead of overwriting, so a stale device cannot erase a session.
A real trust boundary Separate credentials for the game client and for your server, where the shipped one cannot write anything another player can see.
Partial updates Patching one field and reading several keys in one call, so the payload does not grow with the game.
Guest to account Anonymous play that upgrades in place, keeping the same player identity and its data.
Shared values Project-wide documents for drop tables and event flags, readable by clients but writable only server-side.
Environments A development environment whose data cannot touch live players.

Questions Worth Asking Any Provider

These separate a save API from a key-value store with marketing:

  • Can a credential shipped inside my game write another player's data? If the answer is yes, the leaderboard is decorative.
  • What happens when two writes race? "Last write wins" is an answer, but you should hear it out loud before you build on it.
  • Can I patch a field, or must I send the whole document every time?
  • Is there a hard size limit per document, and what happens at it?
  • Does an anonymous player keep their data when they register?
  • Can I read several keys in one request, or is a save load N round trips?

The Practical Summary

Cloud save is not hard because storing JSON is hard. It is hard because the moment saved data becomes visible to other players, the save stops being storage and becomes a rules engine: who may write, what a stale write means, and what happens when the same write arrives twice. A database gives you none of those answers by default, and every team that rolls their own ends up implementing them anyway, usually after the first support ticket.

Crux provides player documents with versioned writes, patching, batch reads, project-scoped shared documents, and a credential split where the key you ship in your game cannot write progression. If you are weighing that against a table you already own, the questions above are the ones that matter.