Improving my data limit / requests?

I’m very concerned about my data request limit, I don’t want to be messing with players data once my game is released. I’m not sure how I would increase my data requests as I’m relatively new to using data stores, got any advice?

Data
local DS = game:GetService("DataStoreService"):GetDataStore("TestData23")
local DataTable = {}

game.Players.PlayerAdded:Connect(function(Plr)

	-- // Load Data.
	
	local Key = "Key" .. Plr.UserId
	local Data = DS:GetAsync(Key) or {
		
		-- // Radio stuff		
		
		EquippedRadio = {EquippedName = "Default", Info = Items.Radios["Default"]},
		
		Radios = {
			["Default"] = {Info = Items.Radios["Default"]},
		},
		
		-- // Trail stuff		
		
		Trails = {
			["None"] = {Info = Items.Trails["None"]}
		},
		
		EquippedTrail = {EquippedName = "None", Info = Items.Trails["None"]},
		
		-- // Pet stuff
		
		Pets = {
			["None"] = {Info = Items.Pets["None"]},		
		},
		
		EquippedPet = {EquippedName = "None", Info = Items.Pets["None"]},
		
		-- // Item stuff		
		
		Inventory = {
			["Default"] = {Info = Items.Tables["Default"]},
		},		
		
		Equipped = {Info = Items.Tables["Default"], EquippedName = "Default"},
		
		-- // Currency stuff
		
		Cash = 125,
		Gems = 0,
	}	
	DataTable[Plr] = Data
	
	-- // Data
	
	game:GetService("ReplicatedStorage").Events.GetData:FireClient(Plr, DataTable[Plr])

	-- // Other.
	
	local AFK = Instance.new("BoolValue", Plr)
	AFK.Name = "AFK"
	AFK.Value = false
	
	local Ready = Instance.new("BoolValue", Plr)
	Ready.Name = "Ready"	
	
	local Intro = Instance.new("BoolValue", Plr)
	Intro.Name = "Intro"
	Intro.Value  = true
	
	local Kills = Instance.new("IntValue", Plr)
	Kills.Name = "Kills"
	
	local Alive = Instance.new("BoolValue", Plr)
	Alive.Name = "Alive"
	
	game:GetService("ReplicatedStorage").Events.UpdateCash:FireClient(Plr, DataTable[Plr])	
		
end)

-- // Save Data.

game.Players.PlayerRemoving:Connect(function(Plr)
	local Key = "Key" .. Plr.UserId
	local Data = DataTable[Plr]
	DS:SetAsync(Key, Data)
end)
1 Like

Wrap your :GetAsync() and :SetAsync() in pcall functions, and repeat them every 6 seconds whenever the pcall fails. There will be cases when either function fails, so if you don’t cover all of your bases, you risk losing player data.

In your case, if the GetAsync fails and then a player decides to leave (after seeing that none of their stats loaded), your script will save a nil value to their file. Quick, easy way to wipe all of their progress. Before you start saving data, set something up to ensure that data successfully loaded first. My own game only runs save loops after data has been loaded, and I haven’t had a data loss report in a very long time.

You also want to set up frequent auto-saving. Popular games generally save data every 60 seconds. This is enough time to make sure that datastore requests don’t run out. This also means that if data fails to save, very little progress would be lost (in the case of a server shutdown). If you just rely on saving when the player leaves, you will get complaints of lost data, and they will get exponentially more frequent as the game gets more popular.

I imagine there’s more things I didn’t cover that others may want to chip in.

2 Likes

What could I add before I load data? I’m still new to using data as I said before.

Right now when you load data, you do this:

local Key = "Key" .. Plr.UserId
local Data = DS:GetAsync(Key)

Looks completely fine, but there’s the issue where GetAsync can fail. If it fails, you’re left with a nil value for that player in your DataTable, which gets saved when they leave.

To prevent GetAsync from failing, you can do something like this:

local Key = "Key" .. Plr.UserId
local Data
local Success, Error
repeat
	Success,Error = pcall(function()
		Data = DS:GetAsync(Key)
	end)
	if not Success then
		print("An issue occurred when loading "..Plr.Name.."'s Data: "..Error)
		wait(1)
	end
until Success or not Plr or not Plr.Parent
if Plr and Plr.Parent then
	if not Data then
		-- Create a new save file
	end
	-- Do stuff with Data now that you're confident it's loaded
	-- Set up a 60-second autosave loop using spawn() or coroutines
end

This will ensure that your data properly loads. It will also stop running if the Player leaves during the loading sequence.

Next, you’ll want to fix your method of saving. Put something like this before you save data:

if DataTable[plr.Name] then
	-- Saving stuff
end

Basically, don’t save the data if the data doesn’t even exist. Your current setup does not account for that.

5 Likes