According to the Data Stores documentation, the cooldown on set requests for the same key is 6 seconds.
When a player is leaving the game, I am saving two separate datastores via UpdateAsync. ExperienceStore and GeneralDataStore
The issue is that requests are getting added to the datastore request queue since both datastores are trying to save upon the player leaving the game.
Is there a reliable way to save multiple datastores as the player leaves without the setting cooldown causing fighting amongst the different stores trying to set their data?
According to the Roblox API, the cooldown is 6 seconds for the same key. Meaning, you can save one data store every 6 seconds. But if you want to save all of them at the same time, you can do it simply.
you would save the player data in a single table here is some demo code
local playerLoaded = {}
game.Players.PlayerAdded:Connect(function(player)
-- when the player enters the game try to load there data
local success, value = pcall(dataStore.GetAsync, dataStore, player.UserId)
if success == false then return end
-- if the value = nil then set value to a empty table
value = value or {}
-- clone the data folder inside this script with all its values
local folder = script.Data:Clone()
-- loop all values and set them to match what was last saved in the datastore
for i, child in ipairs(folder) do child.Value = value[child.Name] or child.Value end
-- place the folder into the player
folder.Parent = player
-- set the playerloaded to true so we can keep track if there are players loaded so that bind to close can wait
playerLoaded[player] = true
end)
game.Players.PlayerRemoving:Connect(function(player)
-- if player loaded == nil meaning the player failed to load when they entered we simple exit because we dont want to overwrite the old data
if playerLoaded[player] == nil then return end
-- create a table and set the the values from there data folder
local playerData = {}
for i, child in ipairs(player.Data:GetChildren()) do
playerData[child.Name] = child.Value
end
-- now save this table to the datastore
local success, value = pcall(dataStore.SetAsync, dataStore, player.UserId, playerData)
-- now set playerLoaded to nil so that bindtoclose can stop looping and allow the server to close
playerLoaded[player] = nil
end)
-- while players are loaded dont close the server (only works upto 30 seconds)
game:BindToClose(function()
while next(playerLoaded) ~= nil do
task.wait()
end
end)