Cloud saves let players continue an HTML5 game across browsers and devices without losing hours of progress. A reliable implementation needs more than uploading one JSON file: it must identify the player, validate game data, handle offline sessions, resolve conflicts, protect privacy, and recover safely when a game updates its save format.
This guide presents a practical architecture for adding cloud save support to an HTML5 game portal while keeping games portable and the player experience understandable.
Define what belongs in a cloud save
Store durable progress such as unlocked levels, achievements, inventory, settings, checkpoint state, and campaign choices. Avoid uploading temporary render state, cached assets, device identifiers, or data that can be recalculated. Smaller saves synchronize faster and are easier to validate.
Each record should include the portal user ID, game ID, save-slot ID, schema version, revision number, updated time, device or session label, checksum, and the validated payload.
{
"game_id": 184,
"slot": "main",
"schema_version": 3,
"revision": 42,
"updated_at": "2026-08-07T10:00:00Z",
"payload": {"level": 12, "coins": 840}
}
Use the portal account as the identity boundary
Games should not receive direct database credentials or trust an arbitrary account ID sent from the browser. The portal authenticates the player, issues a short-lived game-session token, and maps that session to an allowed game. Save APIs then derive user and game identity from the verified session.
If the portal supports social sign-in, the account layer described in our Google login setup guide can provide the stable user identity while cloud saves remain a separate feature.
Design a narrow save API
Expose a small set of endpoints: list slots, read one slot, write a revision, and optionally delete or restore a slot. Require HTTPS, authentication, an allowed game origin, request-size limits, and rate limits.
GET /api/saves/{game}/{slot}reads the latest permitted revision.PUT /api/saves/{game}/{slot}writes only when the expected revision matches.GET /api/saves/{game}/{slot}/historyreturns a small recovery history.POST /api/saves/{game}/{slot}/restorepromotes an earlier valid revision.
Do not let a game query another player’s slots or select arbitrary table fields. Server-side authorization must be applied to every request.
Version every save format
HTML5 games evolve. A field can be renamed, a level system redesigned, or an inventory format replaced. Include a schema version in every payload and ship migration functions with the game or portal integration.
Migrations should be deterministic, tested against real historical examples, and non-destructive. Keep the previous revision until the migrated save loads successfully. If a version is too old to migrate, explain the limitation instead of silently resetting progress.
Prevent accidental overwrites with revisions
A player may open the same game on a laptop and phone. Without concurrency control, the last network request wins even when it contains older progress. Use optimistic locking: the client sends the revision it loaded, and the server accepts the write only if that revision is still current.
When revisions conflict, compare useful signals such as checkpoint, play time, unlocked content, and timestamps. Do not assume the newest timestamp always represents the best progress. Offer the player a clear choice when automatic merging is unsafe.
Support offline play with a sync queue
Browser games should continue working during a temporary connection loss. Store pending changes locally, attach a unique operation ID, and upload them when the portal session returns. The server records processed operation IDs so retries do not duplicate rewards or transactions.
Show a small, unobtrusive state such as saved locally, syncing, cloud saved, or action required. Avoid blocking the game after every checkpoint. A short debounce combines rapid updates into one write.
Handle guest progress carefully
Guest players can keep local saves without a cloud account. When they sign in, ask whether to move or merge guest progress into the account. Never overwrite existing cloud progress automatically just because the local save exists.
This migration can work alongside the discovery and retention patterns in the recently played games feature, but save payloads should remain private and separate from public activity history.
Validate every payload on the server
Client-side game code can be modified. Define a per-game schema with allowed keys, types, ranges, maximum nesting depth, and maximum byte size. Reject unknown or impossible values. Never deserialize executable objects or use save data directly in database queries.
For competitive leaderboards, cloud saves are not proof of a score. Validate scores through the anti-abuse design in our fair leaderboard guide and keep ranking submissions separate from personal progress storage.
Encrypt and minimize sensitive data
Use HTTPS in transit and encryption at rest where appropriate. Store the minimum data needed for gameplay. Do not place email addresses, social-login tokens, advertising identifiers, or chat logs inside game saves. Administrators should access payloads only for defined support or security reasons.
Document retention, deletion, export, and account-removal behavior in the privacy policy and Data Safety declarations. When an account is deleted, remove or anonymize associated saves according to the stated policy and legal requirements.
Keep a small revision history
Players need recovery from corruption, accidental resets, and faulty game updates. Retain a limited number of previous revisions per slot or use a time-based policy. Store checksums and validation results so damaged data is not promoted as a recovery point.
A support screen can show the game, slot, save time, device label, and progress summary without exposing the full payload. Restores should create a new revision so the action remains auditable and reversible.
Optimize synchronization
Compress only when saves are large enough to benefit, cap payload size, and avoid uploading unchanged data. Send checkpoints rather than a request for every coin or movement. Use background sync carefully because browsers may suspend tabs, especially on mobile.
Follow the performance practices in making HTML5 games work better on mobile browsers. Save logic should not block animation frames or create visible stutter.
Expose a stable integration contract
Provide game developers with a small JavaScript SDK that wraps authentication, revision headers, retries, local fallback, and status events. Keep the public contract stable even when the portal changes storage providers.
const save = await PortalSaves.load("main");
await PortalSaves.save("main", nextState, {
expectedRevision: save.revision
});
Document limits, error codes, conflict behavior, and test accounts. A sandbox environment prevents developers from experimenting against production saves.
Test failure scenarios
Test two devices editing the same slot, expired sessions, offline progress, duplicated requests, oversized payloads, schema migrations, database timeouts, account deletion, and corrupted revisions. Also verify touch controls and gameplay remain responsive during synchronization.
Cloud saves should enhance engagement alongside features such as a favorites system, not introduce frequent login prompts or modal interruptions.
Cloud save launch checklist
- Stable account and game-session identity
- Per-game schemas and strict payload limits
- Versioned data with tested migrations
- Optimistic locking and understandable conflict resolution
- Offline queue with idempotent operation IDs
- Safe guest-to-account migration
- Encryption, access controls, retention, export, and deletion
- Revision history and reversible recovery
- Mobile performance and failure-mode tests
Begin with one well-instrumented game and one save slot. Measure write failures, conflicts, recovery requests, payload sizes, and synchronization time. Once the contract is stable, expand cloud saves to more games without making each title invent its own account or storage system.