How can i improve my datastore?

  1. **What do you want to achieve? Keep it simple and clear!
    I want this datastore to eventually hold at least 40+ values, with minimal to no data loss.
    I know I need to implement tables for that but honestly, I don’t know what the best way is to do so.

  2. **What is the issue?
    There is no issue yet, I just want to know what the best way is to improve this.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I’ve asked several social media servers. But none of them really helped.

local players = game:GetService("Players")
local dataStoreService = game:GetService("DataStoreService")
local saveDataStore = dataStoreService:GetDataStore("DataStore11")

players.PlayerAdded:Connect(function(plr)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr
	local Points = Instance.new("IntValue")
	Points.Name = "Points"
	Points.Parent = leaderstats
	local DataId = Instance.new("IntValue")
	DataId.Value = 0
	DataId.Parent = plr
	local data = saveDataStore:GetAsync(plr.UserId)
	if data then
		for name,value in pairs(data.leaderstats) do	
			leaderstats[name].Value = value
		end
	end
end)

players.PlayerRemoving:Connect(function(plr)
	local saveData = {leaderstats = {}}
	for _,stat in pairs(plr.leaderstats:GetChildren()) do
		saveData.leaderstats[stat.Name] = stat.Value
	if saveData then
		saveDataStore:UpdateAsync(plr.UserId, function(oldValue)
			local PreviousData = oldValue or {DataId = 0}
			if saveData.DataId == PreviousData.DataId then
				saveData.DataId = saveData.DataId + 1
				return saveData
			else
					return nil
				end
			end)
		end
	end
end)

	local RunService = game:GetService("RunService")
	if not RunService:IsStudio() then
		game:BindToClose(function()
			for _,plr in pairs(players:GetChildren()) do
				if #game[plr] <= 1 then
					local saveData = {leaderstats = {}}
					for _,stat in pairs(plr.leaderstats:GetChildren()) do
							local success, err = pcall(function()
							saveData.leaderstats[stat.Name] = stat.Value
					end)
						if success then
							print("Data has been saved")
						else
							print("Data has not been saved!")
						end
					end
				end
			end
		end)
	end```
  1. You should unify the logic that serialize your game data into a table since you’re doing that in multiple places - your BindToClose and PlayerRemoving spots.
local function serializePlayerData(player)
    local saveData = { leaderstats = {} }
    for _, stat in pairs(plr.leaderstats:GetChildren()) do
        saveData.leaderstats[stat.Name] = stat.Value -- no need to pcall this
    end
    return saveData
end
  1. Your BindToClose doesn’t actually seem to call any data store functions. It should do this concurrently for all players at once, using the same function which is called for a single player leaving:
local function savePlayerData(player)
    local saveData = serializePlayerData(player)
    saveDataStore:UpdateAsync(...) -- do whatchu gotta do here
end

Here’s how you can do this concurrently:

local players = game.Players:GetPlayers()
local n = 0
for _, player in pairs(players) do
    task.spawn(function ()
        pcall(savePlayerData, player)
        n += 1
    end)
end
-- (There's a better way to do this with an event...
-- ...but I'm being brief here)
while n < #players do wait(1) end
  1. You should wrap every DataStore API call with pcall, as they are all prone to downtime, including your GetAsync call.