Datastore error, Throttled Request was full

Hello!

I have made a tool inventory saving script where it saves the player’s inventory.
However when one guy joined my game, this error appeared:

	❌ Failed to save inventory for Yeyofaterzzz: 304: UpdateAsync request dropped. Request was throttled, but throttled request queue was full.

And this one:

DataStoreService: TransformThrottle: UpdateAsync request dropped. Request was throttled, but throttled request queue was full. API: UpdateAsync, Data Store: ToolPublic

I do not know what these errors do and how do I fix this? Also how would I optimise the Tool Saving script with everything running fine and no disruptions because currently it prints out this warning:

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

Tool Saving Script:

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local player_data = DataStoreService:GetDataStore("ToolPublic")
local RemoveSoldItem = ReplicatedStorage.Remotes.RemoveSoldItem
local LostItem = ReplicatedStorage.Remotes.LostItem

local tools = {} -- Stores both backpack & equipped tools
local CharacterReferences = {}

-- Function to save a player's inventory safely
local function SaveInventory(client)
	if not client then return end -- Safety check

	local key = "client_" .. client.UserId
	local Backpack = client:FindFirstChild("Backpack") or Instance.new("Backpack", client)
	local Character = client.Character
	tools[client] = {BackpackTools = {}, EquippedTools = {}}

	-- ✅ Save tools from Character (equipped tools)
	if Character then
		for _, item in ipairs(Character:GetChildren()) do
			if item:IsA("Tool") then
				table.insert(tools[client].EquippedTools, item.Name)
			end
		end
	end

	-- ✅ Save tools from Backpack
	for _, item in ipairs(Backpack:GetChildren()) do
		if item:IsA("Tool") then
			table.insert(tools[client].BackpackTools, item.Name)
		end
	end

	-- ✅ Safe data saving using UpdateAsync
	local success, err = pcall(function()
		player_data:UpdateAsync(key, function(oldData)
			return tools[client]
		end)
	end)

	if success then
		print("💾 Saved Inventory for " .. client.Name .. ": Equipped[" .. table.concat(tools[client].EquippedTools, ", ") .. "] Backpack[" .. table.concat(tools[client].BackpackTools, ", ") .. "]")
	else
		warn("❌ Failed to save inventory for " .. client.Name .. ": " .. err)
	end
end

-- Function to load a player's inventory
local function LoadInventory(client)
	local key = "client_" .. client.UserId
	local inventory = player_data:GetAsync(key) or {BackpackTools = {}, EquippedTools = {}}
	tools[client] = inventory
	print("📦 Loaded Inventory for " .. client.Name .. ": Equipped[" .. table.concat(inventory.EquippedTools, ", ") .. "] Backpack[" .. table.concat(inventory.BackpackTools, ", ") .. "]")

	local Backpack = client:FindFirstChild("Backpack") or Instance.new("Backpack", client)

	-- Clear existing tools before loading
	for _, item in ipairs(Backpack:GetChildren()) do
		if item:IsA("Tool") then
			item:Destroy()
		end
	end
	local Character = client.Character
	if Character then
		for _, item in ipairs(Character:GetChildren()) do
			if item:IsA("Tool") then
				item:Destroy()
			end
		end
	end

	-- ✅ Load Backpack tools
	for _, name in ipairs(inventory.BackpackTools) do
		local tool = ReplicatedStorage.ItemAssets:FindFirstChild(name) or ReplicatedStorage.LureAssets:FindFirstChild(name)
		if tool then
			local ClonedTool = tool:Clone()
			ClonedTool.Parent = Backpack
			print("✔ Added tool to backpack:", name)
		else
			warn("⚠ Item could not be cloned:", name)
		end
	end

	-- ✅ Load Equipped tools into Character
	if Character then
		for _, name in ipairs(inventory.EquippedTools) do
			local tool = ReplicatedStorage.ItemAssets:FindFirstChild(name) or ReplicatedStorage.LureAssets:FindFirstChild(name)
			if tool then
				local ClonedTool = tool:Clone()
				ClonedTool.Parent = Character
				print("✔ Equipped tool:", name)
			else
				warn("⚠ Item could not be cloned:", name)
			end
		end
	end
end

-- Handles when a player joins
Players.PlayerAdded:Connect(function(client)
	client.CharacterAdded:Wait()
	local char = client.Character
	CharacterReferences[client.UserId] = char
	LoadInventory(client) -- Load inventory on join
end)

-- Handles when a player leaves
Players.PlayerRemoving:Connect(function(client)
	-- ✅ Move equipped tools back to the backpack before saving
	local char = CharacterReferences[client.UserId]
	if char then
		print("Character found before player leaves:", char:GetChildren())
		for _, item in ipairs(char:GetChildren()) do
			if item:IsA("Tool") then
				local itemClone = item:Clone()
				itemClone.Parent = client.Backpack
				item:Destroy()
				print("Moved " .. item.Name .. " to the player's backpack!")
			end
		end
	else
		print("❌ No character found for", client.Name)
	end

	-- ✅ Update tools table with current backpack tools
	local Backpack = client:FindFirstChild("Backpack")
	if Backpack then
		tools[client] = {BackpackTools = {}, EquippedTools = {}}
		for _, item in ipairs(Backpack:GetChildren()) do
			if item:IsA("Tool") then
				table.insert(tools[client].BackpackTools, item.Name)
			end
		end
	end

	-- ✅ Save inventory after moving tools
	SaveInventory(client)

	-- ✅ Cleanup
	CharacterReferences[client.UserId] = nil
	tools[client] = nil
end)

-- Handles item removal when sold
RemoveSoldItem.OnServerEvent:Connect(function(plr, toolItemName)
	if tools[plr] then
		-- Remove from Backpack list
		local TargetPosition = table.find(tools[plr].BackpackTools, toolItemName)
		if TargetPosition then
			table.remove(tools[plr].BackpackTools, TargetPosition)
			print("removed ".. toolItemName)
		end

		-- Remove from Equipped list
		--[[TargetPosition = table.find(tools[plr].EquippedTools, toolItemName)
		if TargetPosition then
			table.remove(tools[plr].EquippedTools, TargetPosition)
		end]]

		-- ✅ Remove tool from player's Backpack or Character
		local Backpack = plr:FindFirstChild("Backpack")
		local Character = plr.Character

		if Backpack then
			local tool = Backpack:FindFirstChild(toolItemName)
			if tool then tool:Destroy() print("removed ".. toolItemName) end
		end

		if Character then
			local tool = Character:FindFirstChild(toolItemName)
			if tool then tool:Destroy() print("removed ".. toolItemName) end
		end

		-- ✅ Immediately save updated inventory
		SaveInventory(plr)
	end
end)

-- Handles lost items
LostItem.OnServerEvent:Connect(function(plr, ItemName)
	if tools[plr] then
		-- Remove from Backpack list
		local TargetPosition = table.find(tools[plr].BackpackTools, ItemName)
		if TargetPosition then
			table.remove(tools[plr].BackpackTools, TargetPosition)
		end

		-- Remove from Equipped list
		TargetPosition = table.find(tools[plr].EquippedTools, ItemName)
		if TargetPosition then
			table.remove(tools[plr].EquippedTools, TargetPosition)
		end

		-- ✅ Remove tool from player's Backpack or Character
		local Backpack = plr:FindFirstChild("Backpack")
		local Character = plr.Character

		if Backpack then
			local tool = Backpack:FindFirstChild(ItemName)
			if tool then tool:Destroy() end
		end

		if Character then
			local tool = Character:FindFirstChild(ItemName)
			if tool then tool:Destroy() end
		end

		-- ✅ Immediately save updated inventory
		SaveInventory(plr)
	end
end)

Thank You!

Bump


the issue could be lying in the fact that save is being called in remote events. If these events are called often it could be causing the issue of throttling. You should only have to save data once, and thats on player leaving, I cant think of a point of needing to save data before leaving. Try removing the save calls out of your events and see if that fixes it.

2 Likes

Wow I didn’t realise that the solution was that easy lol!

Thank you!