Learn how to save and load player data in Roblox Studio using DataStoreService. Step-by-step guide with working Luau code examples for beginners.
A DataStore is how you save player data between sessions in Roblox. Without it, everything resets when the player leaves โ their cash, level, inventory, all gone. DataStores let you store that data permanently on Roblox's servers.
First, make sure API Services are enabled in your game. Go to Game Settings โ Security โ Enable Studio Access to API Services.
Then in a Script inside ServerScriptService:
local DataStoreService = game:GetService("DataStoreService")
local db = DataStoreService:GetDataStore("PlayerData_v1")The string "PlayerData_v1" is just a name โ you can call it anything. Adding a version number (v1, v2) is good practice so you can reset data later if needed.
game.Players.PlayerRemoving:Connect(function(player)
local cash = player.leaderstats and player.leaderstats:FindFirstChild("Cash")
if cash then
local ok, err = pcall(function()
db:SetAsync(player.UserId, { Cash = cash.Value })
end)
if not ok then
warn("Failed to save data for " .. player.Name .. ": " .. err)
end
end
end)Always wrap DataStore calls in pcall. DataStores can fail โ the server might be busy, the player might disconnect mid-save, anything. If you don't use pcall, a failed save will crash your script entirely.
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local cash = Instance.new("IntValue")
cash.Name = "Cash"
cash.Value = 0
cash.Parent = leaderstats
local ok, data = pcall(function()
return db:GetAsync(player.UserId)
end)
if ok and data then
cash.Value = data.Cash or 0
end
end)Players sometimes crash or get disconnected before PlayerRemoving fires. Add a backup auto-save:
task.spawn(function()
while task.wait(60) do
for _, player in ipairs(game.Players:GetPlayers()) do
local cash = player.leaderstats and player.leaderstats:FindFirstChild("Cash")
if cash then
pcall(function()
db:SetAsync(player.UserId, { Cash = cash.Value })
end)
end
end
end
end)Using player.Name instead of player.UserId โ Names can change. UserId is permanent. Always use UserId as your key.
Not using pcall โ DataStore calls can fail. Always wrap them.
Saving too often โ DataStores have rate limits. Don't save on every coin collected or every kill. Save on PlayerRemoving and auto-save every 60 seconds.
Not versioning your data โ If you change what you save (add a new stat), old data won't have it. Always use or defaultValue when reading: data.Cash or 0.
Want a complete working DataStore script you can drop right in? Check out our DataStore Save & Load script โ fully commented and tested.
Browse our free library of copy-paste Luau scripts โ no setup needed.
Browse Script Library โ