Datastore sends errors DataStore request was added to queue. If request queue fills, further requests will be dropped. Try sending fewer requests

The script is just a equip - unequip syncronization with the server
When players clicking the buttons to equip/unequip items, then Im recieving many of the warns “DataStore request was added to queue. If request queue fills, further requests will be dropped. Try sending fewer requests”
I’ve tried using the version below, but its not saving the data, so i modified the script to the second variant and its worked for me, but as i wrote, “DataStore request was added to queue. If request queue fills, further requests will be dropped. Try sending fewer requests” errors.

local DSS = game:GetService("DataStoreService")
local players = game:GetService("Players")

local datastoreName = "test"

local DB = DSS:GetDataStore(datastoreName)
local sessionData = {}

local equipTowerFunction = workspace.ChangeTower
local players = game:GetService("Players")

local function PrintAllDataOfPlayer(player)
	-- Loop through the saved data table and create a new folder for each key-value pair
	for key, value in pairs(sessionData[player.UserId]) do
		print(key,value)
	end
end

local function PrintValueDataOfPlayer(player, valueName)
	-- Loop through the saved data table and create a new folder for each key-value pair
	for key, value in pairs(sessionData[player.UserId]) do
		if key == valueName then
			print(key,value)
		end
	end
end

local function updateDataStoreValue(datastoreName, player, valueName, newValue)
	-- Get the datastore using its name
	local dataStore = DSS:GetDataStore(datastoreName)

	-- Call UpdateAsync to update the value of the key for the player's UserId
	local success, value = pcall(function()
		return dataStore:UpdateAsync(player.UserId, function(oldValue)
			-- Merge the old value with the new value
			local updatedValue = oldValue or {}
			updatedValue[valueName] = newValue

			-- Set the new value
			return updatedValue
		end)
	end)

	-- Check if the update was successful or not
	if success then
		print("Value "..valueName.." updated to: " .. tostring(value))
		print("Now it is:")
		PrintValueDataOfPlayer(player, valueName)
	else
		warn("Error updating value: " .. tostring(value))
	end
end


local tryEquip = function(player, slotName, towerName)
	--players:FindFirstChild(tostring(player)):FindFirstChild("StuffToSave")[tostring(slotName)].Value = towerName
	--надо на серваке изменять и синхронизировать всё
	updateDataStoreValue(datastoreName, player, slotName, towerName)
	print("Function Datastore Updated", slotName, towerName)
	SyncWithDatabase(player)
	return true
end

equipTowerFunction.OnServerInvoke = tryEquip

local function GetNewPlayersData()
	local SS = game:GetService("ServerStorage")
	local dataFolder = SS.StuffToSave
	local data = {}
	
	for i, v in pairs(dataFolder:GetChildren()) do
		data[v.Name] = v.Value
	end
	
	return data
end

local function GetPlayerDataOnServer(player)
	local save = player:WaitForChild("StuffToSave")
	local data = {}

	for i, v in pairs(save:GetChildren()) do
		data[v.Name] = v.Value
	end

	return data
end

function SyncWithDatabase(player)
	local oldData = player:FindFirstChild("StuffToSave")
	if oldData == nil then
		local dataFolder = Instance.new("Folder")
		dataFolder.Name = "StuffToSave"
		dataFolder.Parent = player
	
		-- Loop through the saved data table and create a new folder for each key-value pair
		for key, value in pairs(sessionData[player.UserId]) do
			-- Create a new IntValue instance to store the value
			local newValue = nil
			if type(value) == "number" then
				newValue = Instance.new("IntValue")
			else
				newValue = Instance.new("StringValue")
			end
			newValue.Value = value
			newValue.Name = tostring(key)
			newValue.Parent = dataFolder
		end
	else
		--if player have existing data folder
		
		-- Loop through the saved data table and create a new folder for each key-value pair
		for key, value in pairs(sessionData[player.UserId]) do
			-- Change the existing value
			local newValue = oldData:FindFirstChild(tostring(key))
			newValue.Value = value
		end
		print("synced the data with database and player values in stufftosave")
	end
end

local function PlayerAddedLoadData(player)
	local success = nil
	local playerData = nil
	local attempt = 1

	repeat
		success, playerData = pcall(function()
			return DB:GetAsync(player.UserId)
		end)

		attempt = attempt + 1
		if not success then
			warn(playerData)
			task.wait(3)
		end
	until success or attempt == 5

	if success then
		print("Connected to database for"..player.Name)
		if not playerData then
			print("Assigning data to player", player.Name.."...")
			playerData = GetNewPlayersData()
		end
		sessionData[player.UserId] = playerData
		
		SyncWithDatabase(player)
		
		local loaded = Instance.new("BoolValue")
		loaded.Name = "LOADED"
		loaded.Parent = player
	else
		warn("Failed to load data for"..player.Name)
		player:Kick("Unable to load your data. Try again later!")
	end

end

local function PlayerLeavingSave(player)
	if sessionData[player.UserId] then
		local success = nil
		local errorMessage = nil
		local attempt = 1

		repeat
			success, errorMessage = pcall(function()
				DB:SetAsync(player.UserId, sessionData[player.UserId])
			end)

			attempt = attempt + 1
			if not success then
				warn(errorMessage)
				task.wait(3)
			end
		until success or attempt == 5

		if success then
			print("Data saved for"..player.Name)
		else
			print("Failed to save data for"..player.Name)
		end

	end
end

players.PlayerAdded:Connect(PlayerAddedLoadData)
players.PlayerRemoving:Connect(PlayerLeavingSave)

The script that im using now:

local DSS = game:GetService("DataStoreService")
local players = game:GetService("Players")

local datastoreName = "test2"

local DB = DSS:GetDataStore(datastoreName)
local sessionData = {}

local equipTowerFunction = workspace.ChangeTower
local unequipTowerFunction = workspace.UnequipTower
local players = game:GetService("Players")

local function PrintAllDataOfPlayer(player)
	-- Loop through the saved data table and create a new folder for each key-value pair
	for key, value in pairs(sessionData[player.UserId]) do
		print(key,value)
	end
end

local function PrintValueDataOfPlayer(player, valueName)
	-- Loop through the saved data table and create a new folder for each key-value pair
	for key, value in pairs(sessionData[player.UserId]) do
		if key == valueName then
			print(key,value)
		end
	end
end

local function updateDataStoreValue(player, valueName, newValue)
	local serverData = GetPlayerDataOnServer(player)
	serverData[tostring(valueName)] = newValue
	print(serverData)
	
	local success = nil
	local errorMessage = nil
	local attempt = 1

	repeat
		success, errorMessage = pcall(function()
			DB:SetAsync(player.UserId, serverData)
		end)

		attempt = attempt + 1
		if not success then
			warn(errorMessage)
			task.wait(3)
		end
	until success or attempt == 5

	if success then
		print("Data saved for"..player.Name)
	else
		print("Failed to save data for"..player.Name)
	end
	
	LoadData(player)
end


local tryEquip = function(player, slotName, towerName)
	updateDataStoreValue(player, slotName, towerName)
	return true
end

local unEquip = function(player, slotName)
	updateDataStoreValue(player, slotName, "Nothing")
	return true
end

function GetNewPlayersData()
	local SS = game:GetService("ServerStorage")
	local dataFolder = SS.StuffToSave
	local data = {}
	
	for i, v in pairs(dataFolder:GetChildren()) do
		data[v.Name] = v.Value
	end
	
	return data
end

function GetPlayerDataOnServer(player)
	local save = player:WaitForChild("StuffToSave")
	local data = {}

	for i, v in pairs(save:GetChildren()) do
		data[v.Name] = v.Value
	end

	return data
end

function SyncWithDatabase(player)
	local oldData = player:FindFirstChild("StuffToSave")
	if oldData == nil then
		local dataFolder = Instance.new("Folder")
		dataFolder.Name = "StuffToSave"
		dataFolder.Parent = player
	
		-- Loop through the saved data table and create a new folder for each key-value pair
		for key, value in pairs(sessionData[player.UserId]) do
			-- Create a new IntValue instance to store the value
			local newValue = nil
			if type(value) == "number" then
				newValue = Instance.new("IntValue")
			else
				newValue = Instance.new("StringValue")
			end
			newValue.Value = value
			newValue.Name = tostring(key)
			newValue.Parent = dataFolder
		end
	else
		--if player have existing data folder
		
		-- Loop through the saved data table and create a new folder for each key-value pair
		for key, value in pairs(sessionData[player.UserId]) do
			-- Change the existing value
			local newValue = oldData:FindFirstChild(tostring(key))
			newValue.Value = value
		end
		print("synced the data with database and player values in stufftosave")
	end
end

function LoadData(player)
	local success = nil
	local playerData = nil
	local attempt = 1

	repeat
		success, playerData = pcall(function()
			return DB:GetAsync(player.UserId)
		end)

		attempt = attempt + 1
		if not success then
			warn(playerData)
			task.wait(3)
		end
	until success or attempt == 5

	if success then
		print("Connected to database for"..player.Name)
		if not playerData then
			print("Assigning data to new player", player.Name.."...")
			playerData = GetNewPlayersData()
		end
		sessionData[player.UserId] = playerData
		
		SyncWithDatabase(player)
		
		local loaded = Instance.new("BoolValue")
		loaded.Name = "LOADED"
		loaded.Parent = player
	else
		warn("Failed to load data for"..player.Name)
		player:Kick("Unable to load your data. Try again later!")
	end
end

function PlayerLeavingSave(player)
	if sessionData[player.UserId] then
		local success = nil
		local errorMessage = nil
		local attempt = 1

		repeat
			success, errorMessage = pcall(function()
				DB:SetAsync(player.UserId, sessionData[player.UserId])
			end)

			attempt = attempt + 1
			if not success then
				warn(errorMessage)
				task.wait(3)
			end
		until success or attempt == 5

		if success then
			print("Data saved for"..player.Name)
		else
			print("Failed to save data for"..player.Name)
		end
	end
end

--saves
players.PlayerAdded:Connect(LoadData)
players.PlayerRemoving:Connect(PlayerLeavingSave)

--events remote functions
equipTowerFunction.OnServerInvoke = tryEquip
unequipTowerFunction.OnServerInvoke = unEquip

I would be very grateful if you could tell me what the problem is and advise me how to improve the script in terms of performance

DataStoreService has limits for some reason, you can only make a few requests within a short period of time. I have absolutely no idea why Roblox has this, but it does.

No idea if there’s a way to do this without datastores, but I’ll look

do I need to update the data instead of uploading it to the server? In the first version of the script that I used above, there was no such error, but the data was not updated properly

in the function updateDataStoreValue()

A fix could be saving the data everytime to a folder until the player leaves or every 5 minutes to create fewer requests. I see no need to update the Store everytime something little changes.


it looks like all functions have this limit, although updating can limit reading datastores too

images from

Data store documentation

oh, Michael, you have the pricings in your profile for the simple stuff, can you help me personally?

I think that updating the data would be better then SetAsync to prevent data loss if the callback returns nil. Also prior versions are accessible in the event an issue occurs. Would you agree @N0TKingminer7?

If you wish to commission me contact myself at mike.#0001 on Discord, cheers.

the problem is still not solved, Michael refused to help me directly

The problem you are having is that you’re being rate limited. You need to either slow down the request rate, or only use requests every so often. The best option would be to add what’s known as a Cache.
A cache stores the current player’s data without uploading the data to the server. Then once the player leaves/disconnects, the data contained within the cache will be sent to the server and stored. I suggest you try out one of the open source datastore saving modules such as Datastore2 or ProfileService

Datastore2:

ProfileService:

it looks like a miracle that fell from heaven. Now I’ll try to code something with this datastore2

1 Like

image
in the combine method, the first argument is the name of the DB?

Yeah, that’s called the MasterKey, it stored all the other ‘data’. For example using .Combine() for coins, rebirths and level:

datastore2.Combine("MasterKey", "Coins", "Rebirths", "Level")

If you have any other questions which aren’t a part of the primary topic’s thread then message me; Nonopter#5706

1 Like

how kind you are! I sent you a friend request

function tryEquip(player, slotName, towerName)
print(player, slotName, towerName)
local store = DataStore2(datastoreName, player)

-- Get the player's current data
local data = store:Get()

-- Update the value for the given slot with the new tower name
data[slotName] = towerName

-- Set the updated data to the datastore
store:Set(data)

-- Sync the updated data with the player's data folder
local dataFolder = player:FindFirstChild("StuffToSave")
if not dataFolder then
	dataFolder = Instance.new("Folder")
	dataFolder.Name = "StuffToSave"
	dataFolder.Parent = player
end

-- Find the existing value in the data folder, or create a new one if it doesn't exist
local dataValue = dataFolder[slotName]
if not dataValue then
	dataValue = Instance.new("StringValue")
	dataValue.Name = slotName
	dataValue.Parent = dataFolder
end

-- Update the value in the data folder to match the value in the datastore
dataValue.Value = towerName

print("Equipped tower", towerName, "in slot", slotName)

end

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.