Syntax
local store = game:GetService("DataStoreService"):GetDataStore("LessonProgress_TEST_v1")Examples
Choose an explicit test namespace
Script in ServerScriptService of a separate published test experience. Enable Studio API access only for that test experience. This obtains a store handle; it does not read or write data yet.
local DataStoreService = game:GetService("DataStoreService")
local store = DataStoreService:GetDataStore("LessonProgress_TEST_v1")
local function playerKey(userId: number): string
return "player:" .. tostring(userId)
end
print("Test key:", playerKey(12345))Inspect a request budget
Separate server Script in the test experience. A budget value is a point-in-time hint, not a reservation or a promise that the next request succeeds. All requests still need protected calls and a failure path.
local DataStoreService = game:GetService("DataStoreService")
local budget = DataStoreService:GetRequestBudgetForRequestType(Enum.DataStoreRequestType.GetAsync)
print("Current read budget:", budget)
if budget < 1 then
warn("Defer non-essential reads instead of starting a burst")
endBest practices
- Do not test against production player keys; a different key alone is weaker isolation than a separate experience.
- Use stable UserId-based keys rather than names.
- Plan for throttling, unavailable services, schema changes and failed saves before relying on persistence.
At a glance
- Purpose
- Typed scripting and Roblox development
- File extension
- .luau
- Runs in
- Luau host; Roblox engine examples require Roblox Studio
- Usually used with
- Roblox APIs and Studio
Specifications & further reading
Related Luau documentation
Load and validate player data
A successful read returning nil means no stored value exists. A failed read means the value is unknown. Those cases must never share a fallback that later saves defaults over real data. Validate stored fields before marking a session ready.UpdateAsync and concurrent writes
UpdateAsync lets a non-yielding callback transform the latest value. It may invoke that callback again after a conflict. This example saves a monotonic highest-lesson record with max; that merge rule is appropriate for progress that never decreases, not balances, inventories or resets.Handling errors with pcall and xpcall
Protected calls turn an exception into a success flag and a result. They are useful around operations that can fail outside your control. They do not repair bad state, retry automatically, or mean every error should be ignored.Retries, autosave and shutdown limits
A save can fail after gameplay succeeded. Keep the ready session available for another attempt, retry only a bounded number of times and report unresolved failures. PlayerRemoving and BindToClose are opportunities to save, not guarantees of durability.
A successful read returning nil means no stored value exists. A failed read means the value is unknown. Those cases must never share a fallback that later saves defaults over real data. Validate stored fields before marking a session ready.UpdateAsync and concurrent writes
UpdateAsync lets a non-yielding callback transform the latest value. It may invoke that callback again after a conflict. This example saves a monotonic highest-lesson record with max; that merge rule is appropriate for progress that never decreases, not balances, inventories or resets.Handling errors with pcall and xpcall
Protected calls turn an exception into a success flag and a result. They are useful around operations that can fail outside your control. They do not repair bad state, retry automatically, or mean every error should be ignored.Retries, autosave and shutdown limits
A save can fail after gameplay succeeded. Keep the ready session available for another attempt, retry only a bounded number of times and report unresolved failures. PlayerRemoving and BindToClose are opportunities to save, not guarantees of durability.