DataStore request was added to the queue - How would I fix this issue?

-- This code should be in a 'Script' object within 'ServerScriptService'
local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local RobuxDonatedDataStore = DataStoreService:GetDataStore("RobuxDonated", "RobuxDonatedScope")
 
local function processReceipt(receiptInfo)
	
	-- Find the player who made the purchase in the server
	local player = game:GetService("Players"):GetPlayerByUserId(receiptInfo.PlayerId)
	if not player then
		-- The player probably left the game
		-- If they come back, the callback will be called again
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end
	
	-- Output what product they bought
	print(receiptInfo.PlayerId .. " just bought " .. receiptInfo.ProductId)
	if receiptInfo.ProductId == 555817714 then
		pcall(function()
			player.leaderstats.RobuxDonated.Value = player.leaderstats.RobuxDonated.Value + 10
			RobuxDonatedDataStore:SetAsync(player.Name, player.leaderstats.RobuxDonated.Value)
			print("Saved!")
		end)
	elseif receiptInfo.ProductId == 555817949 then
		pcall(function()
			player.leaderstats.RobuxDonated.Value = player.leaderstats.RobuxDonated.Value + 50
			RobuxDonatedDataStore:SetAsync(player.Name, player.leaderstats.RobuxDonated.Value)
			print("Saved!")
		end)
	elseif receiptInfo.ProductId == 555818101 then
		pcall(function()
			player.leaderstats.RobuxDonated.Value = player.leaderstats.RobuxDonated.Value + 100
			RobuxDonatedDataStore:SetAsync(player.Name, player.leaderstats.RobuxDonated.Value)
			print("Saved!")
		end)
	end
	
	-- IMPORTANT: Tell Roblox that the game successfully handled the purchase
	return Enum.ProductPurchaseDecision.PurchaseGranted
end

 
-- Set the callback (this can only be done once by one script on the server!)
MarketplaceService.ProcessReceipt = processReceipt

The code above shows how I handle Developer Product purchases and when a player leaves the game.
However, there is a warning that said:

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

This happens if a player purchases Developer Products too quickly.
How would I send fewer requests so that this warning would go away?

1 Like

This doesn’t answer your initial question, but you should use the player’s ID as a key. Using their name is a really really bad idea as users can change their username easily.

5 Likes

I remember being excited after changing my username only to lose all my data on my favourite game a few years ago :disappointed_relieved: dont make the same mistake they did

2 Likes

You should place the Robux Donated things in a queue that only uses DataStores once every x minutes. Once every 1 minute may be enough. The reason behind this is to prevent multiple DataStore usage all at once when players purchase developer products a lot of times within a short period of time.

Example code:

local playerQueue = {}
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService'Players'
local DataStoreService = game:GetService("DataStoreService")
local RobuxDonatedDataStore = DataStoreService:GetDataStore("RobuxDonated", "RobuxDonatedScope")

coroutine.wrap(function()
	while true do
		wait(60)
		for player, addedRobux in pairs(playerQueue) do
			local success, newData = pcall(function() --use pcall for datastores!
				return RobuxDonatedDataStore:SetAsync(player.Name, addedRobux) --PSA: Don't use Player Names in storing data! Use IDs instead
			end)
			if not success then
				--do error handling here for when the data fails to save!
			else
				print('Saved!')
			end
			playerQueue[player] = nil
		end
	end
end)()

local function processReceipt(receiptInfo)
		-- Find the player who made the purchase in the server
	local player = game:GetService("Players"):GetPlayerByUserId(receiptInfo.PlayerId)
	if not player then
		-- The player probably left the game
		-- If they come back, the callback will be called again
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end
	
	-- Output what product they bought
	print(receiptInfo.PlayerId .. " just bought " .. receiptInfo.ProductId)
	if receiptInfo.ProductId == 555817714 then
		pcall(function()
			player.leaderstats.RobuxDonated.Value = player.leaderstats.RobuxDonated.Value + 10
			playerQueue[player] = player.leaderstats.RobuxDonated.Value
		end)
	elseif receiptInfo.ProductId == 555817949 then
		pcall(function()
			player.leaderstats.RobuxDonated.Value = player.leaderstats.RobuxDonated.Value + 50
			playerQueue[player] = player.leaderstats.RobuxDonated.Value
		end)
	elseif receiptInfo.ProductId == 555818101 then
		pcall(function()
			player.leaderstats.RobuxDonated.Value = player.leaderstats.RobuxDonated.Value + 100
			playerQueue[player] = player.leaderstats.RobuxDonated.Value
		end)
	end
	
	-- IMPORTANT: Tell Roblox that the game successfully handled the purchase
	return Enum.ProductPurchaseDecision.PurchaseGranted
end

local function onPlayerLeave(player) --this is important so that the player's data will save when they leave before the interval! not doing this may send the player to a server with the outdated data. 
	if playerQueue[player] then
		local success, newData = pcall(function() --use pcall for datastores!
			return RobuxDonatedDataStore:SetAsync(player.Name, playerQueue[player]) --PSA: Don't use Player Names in storing data! Use IDs instead
		end)
		if not success then
			--do error handling here for when the data fails to save!
		else
			print('Saved!')
		end
		playerQueue[player] = nil
	end
end

-- Set the callback (this can only be done once by one script on the server!)
MarketplaceService.ProcessReceipt = processReceipt
Players.PlayerRemoving:Connect(onPlayerLeave)

PS: This is just an example code. I haven’t tested it but doing that should fix the issue you’re experiencing :slightly_smiling_face:

2 Likes

Thanks for the solution! I had a different idea that involved making a cooldown before purchasing a DeveloperProduct, but this works! :smiley:

1 Like