Datastore help needed!

I have a datastore saving 20+ values. However, I keep getting this warning in the output. I need help optimizing this.

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

local DataStoreService = game:GetService("DataStoreService")
local MyDataStore = DataStoreService:GetDataStore("MainDataStore")

local function AddData(player)
	local data = script.Data:Clone()
	data.Parent = player

	for _, Child in pairs(data:GetChildren()) do
		Child.Parent = data.Parent
	end

	data:Destroy()
end

local function extractFromTable(Table, folder)
	for _, Value in pairs(folder:GetChildren()) do
		if Value:IsA("BoolValue") then
			local ValueName = Value.Name
			Value.Value = Table[ValueName] or false
		elseif Value:IsA("IntValue") then
			local ValueName = Value.Name
			Value.Value = Table[ValueName] or 0
		elseif Value:IsA("StringValue") then
			local ValueName = Value.Name
			if Value:GetAttribute("Ship") ~= nil then
				Value.Value = Table[ValueName] or "Dmg: 1, Speed: 1"
			else
				Value.Value = Table[ValueName] or ""
			end
		elseif Value:IsA("Color3Value") then
			local ValueName = Value.Name
			local Color3Table = Table[ValueName]
			if Color3Table then
				Value.Value = Color3.new(Color3Table.R, Color3Table.G, Color3Table.B)
			else
				Value.Value = Color3.new(0, 0, 0) -- Default to white if not found in the table
			end
		end
	end
end

local function insertIntoTable(Table, folder)
	for _, Value in pairs(folder:GetChildren()) do
		if Value:IsA("BoolValue") then
			local ValueName = Value.Name
			Table[ValueName] = Value.Value
		elseif Value:IsA("IntValue") then
			local ValueName = Value.Name
			Table[ValueName] = Value.Value
		elseif Value:IsA("StringValue") then
			print(Value.Value)
			local ValueName = Value.Name
			Table[ValueName] = Value.Value
		elseif Value:IsA("Color3Value") then
			local colorTable = {
				R = Value.Value.R,
				B = Value.Value.B,
				G = Value.Value.G
			}
			local ValueName = Value.Name
			Table[ValueName] = colorTable		
		end
	end
end

local function CreateData(player)
	AddData(player)

	local Currency = player:WaitForChild("leaderstats").Checks
	local Ore = player:WaitForChild("OreFolder")
	local Quests = player:WaitForChild("Quests")
	local Shipstats = player:WaitForChild("Shipstats")
	local shopFolder = player:WaitForChild("ShopFolder")
	local Misc = player:WaitForChild("Misc")

	local success, LoadedData = pcall(function()
		return MyDataStore:GetAsync(tostring(player.UserId)) or {}
	end)

	if success then
		Currency.Value = LoadedData.Coins or Currency.Value
		local ShopColor = shopFolder:WaitForChild("ShopColor")
		ShopColor.Value = Color3.new(LoadedData.R, LoadedData.G, LoadedData.B)

		extractFromTable(LoadedData, Ore)
		extractFromTable(LoadedData, Quests)
		extractFromTable(LoadedData, Shipstats)
		extractFromTable(LoadedData, shopFolder)
		extractFromTable(LoadedData, Misc)

		print("Data loaded successfully for player " .. player.Name)
	else
		warn("Failed to load data for player " .. player.Name)
	end
end

function SaveData(player)
	
	local Currency = player:WaitForChild("leaderstats").Checks
	local Ore = player:WaitForChild("OreFolder")
	local Quests = player:WaitForChild("Quests")
	local Shipstats = player:WaitForChild("Shipstats")
	local shopFolder = player:WaitForChild("ShopFolder")
	local Misc = player:WaitForChild("Misc")

	local dataToSave = {
		Currency = Currency.Value,
	}

	insertIntoTable(dataToSave, Ore)
	insertIntoTable(dataToSave, Quests)
	insertIntoTable(dataToSave, Shipstats)
	insertIntoTable(dataToSave, shopFolder)
	insertIntoTable(dataToSave, Misc)
	
	print(dataToSave)

	local success, error = pcall(function()
		MyDataStore:SetAsync(tostring(player.UserId), dataToSave)
	end)

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

function Shutdown()
	for _, player in pairs(game.Players:GetPlayers()) do
		SaveData(player)
	end
end

game.Players.PlayerAdded:Connect(CreateData)
game.Players.PlayerRemoving:Connect(SaveData)
game:BindToClose(Shutdown)

while wait(300) do
	for _, player in pairs(game.Players:GetPlayers()) do
		SaveData(player)
	end
end
3 Likes

maybe shutdown and player removing running at the same time ? try to delete bindtoclose and see what will happen ?

No, I don’t think so. BindToClose is only called when the server shuts down, not when the player leaves.

it will run even in studio . just try to remove it and rerun ?

1 Like

Alright, I will try to remove it and see what happens.

Nope, still getting the same warning

1 Like

I think there is too much demand at the data store.
Try:

  • Back up data every 10-15 minutes instead of 5
  • Back up data when it changes
  • DataStoreService.AutomaticRetry Try this, it automatically retries when requests fail
  • DataStoreService:ThrottleAsync() Try this, it lets you see how many requests you can make before reaching the limit
2 Likes

Okay. This looks interesting. How would I go about implementing this into my code? (I still get the throttling when I remove the time-based-saving system.)

I wouldn’t be worried about that error as I get it all the time and there are no problems with the datastore. it still will save.

1 Like

I know, but with large amounts of players in-game, it could cause problems. You never want to lose your players data.

I don’t know, I’ll try to see but scripting is not my job

1 Like

hm have u ever change your mind to use profileservice ? its very easy to use once u understand

example : very useful
Profile-Service-Guide.rbxl (67.4 KB)

2 Likes

I have looked into it in the past, but my current game is already implemented with the default Roblox datastore API, so I would prefer not switching at this point.

Hello, have you tried using profile service ProfileService? It would cover all your database needs.

1 Like

very no no no whats the point of warning then we the one need to fix it , i might agree but its not 100% save once your active players more than thousand

1 Like

If you are not experienced scripter, then I would not recommend continuing with your own database script. In short, chance of data loss is higher with your method.

I have several years of scripting experience, and I feel that I can handle this system. However, I did run across this problem, and I want to learn how to fix it, instead of just transferring to something easier.

well i searched your game , i think you better change it before your game hyped . thats the only way OR save old data to profileservice

What do you mean ‘searched your game’ and ‘hyped’?

Oh, Good to know. Also …

Wouldn’t this be perserver not in total of players in a game? Like if the server had 8 players in a server and 3000 players in a game in total on separate servers would their be data loss still?