Datastores requests are getting added to queue and I don't know how to fix it

I was trying to find a datastore script that was easy to work with so I can use it for my game. I successfully got it to work how I intended it to, but I noticed something in studio AND in game. This warning that says something like, “Datastore requests are getting added to queue. Try sending fewer requests.” was showing up (note that there are coins in my game and the player is supposed to constantly collect them). When I tested this in game, my data would only save the first few times I collected some coins. I think it has something to do with datastore saving progress too fast, but I don’t know how to solve that

script (original not made by me. I only modified it a tiny bit to better suit my game):

local players = game:GetService("Players")
local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("CoinValueSaver") 
local ds2 = datastore:GetDataStore("MaterialValueSaver") 

players.PlayerAdded:connect(function(player)
 local folder = Instance.new("Folder")
 folder.Name = "leaderstats"
 folder.Parent = player
	
	
	
	
 local currency1 = Instance.new("IntValue")
 currency1.Name = "Coins"
 currency1.Parent = player.leaderstats
	currency1.Value = ds1:GetAsync(player.UserId) or 0
	ds1:SetAsync(player.UserId, currency1.Value)
	
	
	
	
	
local currency2 = Instance.new("IntValue")
 currency2.Name = "Materials"
 currency2.Parent = player.leaderstats
	currency2.Value = ds2:GetAsync(player.UserId) or 0
 ds2:SetAsync(player.UserId, currency2.Value)
	
	
	
	
	currency1.Changed:connect(function()
  ds1:SetAsync(player.UserId, currency1.Value)
	end)
	
	
	
	
	
	currency2.Changed:connect(function()
  ds2:SetAsync(player.UserId, currency2.Value)
 end) 
end)
1 Like

You are attempting to set data to your datastores way to often.
You should update the player’s data when something significant in the game happens or when the player leaves.

The currency values are probably changing too frequently, especially with multiple players in a server.

Instead of saving the data everytime the values change, save both of the values whenever the player leaves the server, or when the server is shutting down (BindToClose).

Also, I suggest combining the DataStores, instead of having two separate ones. Instead of ds1 and ds2, make one DataStore. Inside this DataStore, you can put a table containing the coin value and material value.

but how would I do that though?

You Should Save Data in A Table
Instead of Saving All of them Separately.

If you save them Separately there will be Mass
Data Saving Requests.

I will create an example for you now.

you should save at the end of the game, not a auto save

auto save systems are bad in general(depending on how you implement it)

local CreateLeaderstats = function(Player, Data)
	--Do leaderstats
	--To update a value do Currency1.Value = Data.Currency1
end

game.Players.PlayerAdded:Connect(function(Player)
	local Success, Data = pcall(function()
		return Datastore:GetAsync(Player.UserId)
	end)
	
	if Success then
		if Data then --Check if player has played before
			CreateLeaderstats(Player, Data)
		else
			--If not create new data for them
			local Data = {
				["Currency1"] = 0,
				["Currency2"] = 0
			}
			CreateLeaderstats(Player, Data)
		end
	else
		--Request dropped
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	local Data = {
		["Currency1"] = Player.leaderstats.Currency1.Value,
		["Currency2"] = Player.leaderstats.Currency2.Value
	}
	Datastore:SetAsync(Player.UserId, Data)
end)

local RunService = game:GetService("RunService")
local players = game:GetService("Players")

local datastore = game:GetService("DataStoreService")
local currencyStore = datastore:GetDataStore("currencyStoring")

players.PlayerAdded:connect(function(player)
	local folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	folder.Parent = player

	local currency1 = Instance.new("IntValue")
	currency1.Name = "Coins"
	currency1.Parent = folder

	local currency2 = Instance.new("IntValue")
	currency2.Name = "Materials"
	currency2.Parent = folder
	
	local data
	local found,new = pcall(function()
		data = currencyStore:GetAsync(player.UserId)
	end)
	if data and found then
		currency2.Value = data.Materials
		currency1.Value = data.Coins
	else
		print("New Player")
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	local success,Error = pcall(function()
		currencyStore:SetAsync(Player.UserId{
			Coins = Player.leaderstats.Coins.Value,
       		Materials = Player.leaderstats.Materials.Value
		})
	end)
	if not success then warn(Error) end
end)

game:BindToClose(function()
	if RunService:IsStudio() then
		wait(1)
	else
		for _,localplayer in pairs(players) do
			local success, Error = pcall(function()
				currencyStore:SetAsync(localplayer.UserId{
					Coins = localplayer.leaderstats.Coins.Value,
					Materials = localplayer.leaderstats.Materials.Value
				})
			end)
            if not success then warn(Error) end
		end
	end
end)

Here We save data As a table, And when the Player leaves.
This should prevent Data Requests Getting In Queue.

1 Like

this IS a solution to my problem, but I would like to know how this script works aswell… Could you please explain?

local RunService = game:GetService("RunService") -- Define Run Service
local players = game:GetService("Players") -- Get Players Service

local datastore = game:GetService("DataStoreService") -- Define DataStore Service
local currencyStore = datastore:GetDataStore("currencyStoring") -- Create A DataStore

players.PlayerAdded:connect(function(player) -- When Player Joins
	local folder = Instance.new("Folder") -- Insert A Folder 
	folder.Name = "leaderstats" -- Call the Folder leaderstats
	folder.Parent = player -- Folder's Parent is Player

	local currency1 = Instance.new("IntValue") -- Insert a Value
	currency1.Name = "Coins" -- Value is called Coins
	currency1.Parent = folder -- Parent is The Folder

	local currency2 = Instance.new("IntValue") -- Insert A Value
	currency2.Name = "Materials"-- Value is called Materials
        currency2.Parent = folder -- Parent is The Folder
	
	local data -- Make a Blank Variable (We Dont need this Now)
	local found,new = pcall(function() -- Pcall Basically Prevents the Scripts from Breaking If we Have an Error.
		data = currencyStore:GetAsync(player.UserId) -- If We Find data with the Player's UserId
	end)
	if data and found then -- Check if data Exists
		currency2.Value = data.Materials --  Set Currency2 (Materials) Value to the Materials Value we Saved in the Table
		currency1.Value = data.Coins -- Set Currency1 (Coins) Value to the Coins Value we Saved in the Table
	else
		print("New Player") -- If we Have no data it Means the Player is New to Game
	end
end)

game.Players.PlayerRemoving:Connect(function(Player) -- When Player Leavs
	local success,Error = pcall(function() -- Wrap in Pcall so script does not Break if we get An error
		currencyStore:SetAsync(Player.UserId{ -- Save Data with the Players UserId
			Coins = Player.leaderstats.Coins.Value, -- Set Coins To Player's Coins Value
       		Materials = Player.leaderstats.Materials.Value -- Set Materials to Player's Materials Value
		})
	end)
	if not success then warn(Error) end -- If we get an Error we "warn" which basically says what caused the Error.
end)

game:BindToClose(function() -- When server is Closing Because of Error or anything
	if RunService:IsStudio() then -- If We are Testing in Studio
		wait(1) -- We wait 1 Second so that We can Save Data from PlayerRemoving Above
	else -- If Its actual Game
		for _,localplayer in pairs(players) do -- Loop through All Players in game
			local success, Error = pcall(function() -- Wrap in Pcall so script does not break in case of an error
				currencyStore:SetAsync(localplayer.UserId{ -- Save Data With UserId
					Coins = localplayer.leaderstats.Coins.Value, -- Set "Coins" in the Table to Player's Coins
					Materials = localplayer.leaderstats.Materials.Value -- Set "Materials" In the Table to Player's Materials
				})
			end)
            if not success then warn(Error) end -- If we get An Error while Saving, We "Warn" it, Which tells us what caused the error.
		end
	end
end)

I Tried my best to Explain What i Did in this Script.
If you still Want to learn More,

You can Look up
Here

1 Like

I got an error: “ServerScriptService.Mainleaderstats:34: attempt to call a number value”

what do I do?

local RunService = game:GetService("RunService") -- Define Run Service
local players = game:GetService("Players") -- Get Players Service

local datastore = game:GetService("DataStoreService") -- Define DataStore Service
local currencyStore = datastore:GetDataStore("currencyStoring") -- Create A DataStore

players.PlayerAdded:connect(function(player) -- When Player Joins
	local folder = Instance.new("Folder") -- Insert A Folder 
	folder.Name = "leaderstats" -- Call the Folder leaderstats
	folder.Parent = player -- Folder's Parent is Player

	local currency1 = Instance.new("IntValue") -- Insert a Value
	currency1.Name = "Coins" -- Value is called Coins
	currency1.Parent = folder -- Parent is The Folder

	local currency2 = Instance.new("IntValue") -- Insert A Value
	currency2.Name = "Materials"-- Value is called Materials
	currency2.Parent = folder -- Parent is The Folder

	local data -- Make a Blank Variable (We Dont need this Now)
	local found,new = pcall(function() -- Pcall Basically Prevents the Scripts from Breaking If we Have an Error.
		data = currencyStore:GetAsync(player.UserId) -- If We Find data with the Player's UserId
	end)
	if data and found then -- Check if data Exists
		currency2.Value = data.Materials --  Set Currency2 (Materials) Value to the Materials Value we Saved in the Table
		currency1.Value = data.Coins -- Set Currency1 (Coins) Value to the Coins Value we Saved in the Table
	else
		print("New Player") -- If we Have no data it Means the Player is New to Game
	end
end)

game.Players.PlayerRemoving:Connect(function(Player) -- When Player Leavs
	local success,Error = pcall(function() -- Wrap in Pcall so script does not Break if we get An error
		currencyStore:SetAsync(Player.UserId,{ -- Save Data with the Players UserId
			Coins = Player.leaderstats.Coins.Value, -- Set Coins To Player's Coins Value
			Materials = Player.leaderstats.Materials.Value -- Set Materials to Player's Materials Value
		})
	end)
	if not success then warn(Error) end -- If we get an Error we "warn" which basically says what caused the Error.
end)

game:BindToClose(function() -- When server is Closing Because of Error or anything
	if RunService:IsStudio() then -- If We are Testing in Studio
		wait(1) -- We wait 1 Second so that We can Save Data from PlayerRemoving Above
	else -- If Its actual Game
		for _,localplayer in pairs(players) do -- Loop through All Players in game
			local success, Error = pcall(function() -- Wrap in Pcall so script does not break in case of an error
				currencyStore:SetAsync(localplayer.UserId,{ -- Save Data With UserId
					Coins = localplayer.leaderstats.Coins.Value, -- Set "Coins" in the Table to Player's Coins
					Materials = localplayer.leaderstats.Materials.Value -- Set "Materials" In the Table to Player's Materials
				})
			end)
			if not success then warn(Error) end -- If we get An Error while Saving, We "Warn" it, Which tells us what caused the error.
		end
	end
end)

The Problem was That i forgot to Put a , (comma).
Fixed it :grinning_face_with_smiling_eyes:

3 Likes