roblox data persistence
When to Load
Load when designing player saves, schema migrations, retries, shutdown handling, or session ownership. Use roblox-server-data for ordered leaderboards, messaging, and world data; roblox-cloud for Open Cloud.
Quick Reference
- Define a serializable template and a version field before storing player state. Deep-copy templates so nested defaults are not shared; migrate, then reconcile missing fields against the template. Scope store names by environment (
PlayerData_Studio) so Studio writes stay out of production. - Use
UpdateAsyncfor read-modify-write; handle throttling and transient errors. - Prevent two servers mutating one profile at once: a session-ownership wrapper or equivalent protocol.
- With ProfileStore:
StartSessionAsync,Profile.OnSessionEnd,EndSessionas documented; noStealfor normal loads;ProfileStore.Mockfor ephemeral Studio writes. - Save on meaningful changes and lifecycle boundaries;
PlayerRemovingalone is not sufficient.BindToClosefinishes pending work. - Store primitives, arrays, dictionaries; convert Instances/userdata/functions/cyclic tables first. Validate numbers (no NaN/inf), strings (
utf8.len), nested tables: one bad value fails the write. - RTBF: keep the user ID as a static substring in keys (
player_<UserId>) so{UserId}deletion templates can match; hashed or random keys make erasure manual. GetAsyncserves a 4-second local cache (DataStoreGetOptions.UseCache, defaulttrue); verify writes withUseCache = false.- Poll
DataStoreService:GetRequestBudgetForRequestTypefor live headroom; quotas scale with concurrent users (experience reads: 300 + concurrentUsers x 40/min). - New code identifies users with
player.User(User.Id,DomainType,DomainId);UserIdremains valid, but never mix the two IDs in one key scheme.
Need details? references/full.md has the framework-neutral persistence design.