Datastore throttling

Today my co-developer added pickable coins to the map of our game. The problem is when a player collects coins sometimes the datastore will throttle. Here is my script that saves the coins:

local DataStoreService = game:GetService("DataStoreService")
local mainDataStore = DataStoreService:GetDataStore("MainDataStore")

LocalPlayer.Money:GetPropertyChangedSignal("Value"):Connect(function()
	local success, err = pcall(function()
		mainDataStore:SetAsync(LocalPlayer.UserId.."_Money", LocalPlayer.Money.Value)
	end)
	
	if success then
		print("Data saved successfully!")
	else
		warn("Error saving player money data Error saving player money data for "..LocalPlayer.Name.." Error: "..err)
	end
end)

I checked datastore limits on Roblox Developer website and it seems like there must be at least 6 seconds delay between write requests.


So what that mens is if the player picks up a coin, runs to another coin and picks it up in less than 6 seconds the datastore will throttle.

So my questions are:

  • Why Roblox had to implement a limitation that is pain in the ass
  • Is there any way around it
  • Are there any better ways to write my coin saving script

This seems inefficient as you are calling an asynchronous request function every time the player gains a coin. It might be better to save every player’s data periodically every few minutes or when they exit the game.

3 Likes

If player is the last one left in the server and leaves sometimes their data would not be saved. game:BindToClose freezes my studio window for 30 seconds each time I press stop.

Use RunService:IsStudio() to stop this. Additionally, make sure you save data when the player leaves and only if their data could be loaded successfully. Don’t save when a value changes.

Store all player data in a single table, do not save values individually unless necessary.

4 Likes

You can have a table for each players data and have an auto save that will only save when the players data has changed. Even when the player leaves only save the data if it has changed.

So have the players data table.
Also have a PlayerToSave table.
If a value for the player is changed, update the player data table and also use the player object as the key for the playertosave table like this

PlayersToSave[player] = true

then have a wait time(1-2 mins or how ever long you want…) before checking if their are any players that need to be saved

local function autosave()   -- called on initial script run
	while wait(autosavetime) do  -- the loop that waits what ever auto save time you have set
		for player, data in pairs(PlayersToSave) do  -- loop through any players that data has changed on
			savePlayerData(player)  -- saves that players data
			PlayersToSave[player] = nil   -- removes from tosave table since the data has now been saved
			print('AutoSaved ',player) -- just a print..
		end
	end
end

Also on your player leaving game you want to save their data table only if they are in the PlayerToSave table… else no reason to save because nothing has changed…

game.Players.PlayerRemoving:connect(function(player)
	if PlayersToSave[player] then  -- if players data changed and needs to be saved
		savePlayerData(player)  -- save the data
		print('LeaveSaved ',player)   -- just a print..
	end
	PlayersToSave[player] = nil  -- just removes from table since it has been saved
end
2 Likes