How to stop datastore from lagging the player when they leave?

Hi.

So I made a basic datastore script which basically saves string values (there are multiple of them) and when I leave in studio, it freezes/hangs for 5-20 seconds then closes. I get this warning:
image

Script:
game:GetService("Players").PlayerRemoving:Connect(function(Player)
	pcall(function()
	local DataKey = Player.UserId.."-save"

	local Binds = Player:WaitForChild("Keybinds")
	local Keys = {}

	for _, Index in pairs(Binds:GetChildren()) do
		if Index:IsA("Folder") then
			Keys[Index.Name] = {}

			for i, values in pairs(Index:GetChildren()) do
					if values:IsA("StringValue") then
				
					Keys[Index.Name][values.Name] = values.Value
                  DataModule.SaveData(DataKey, BindDataStore, Keys)
				end
			end
		end
	end
	end)
end)

Module:


local DataSaver = {}

function DataSaver.SaveData(key, datastore, data)
	datastore:SetAsync(key, data)
end

function DataSaver.LoadData(key, datastore)
	local data =  datastore:GetAsync(key)
	
	return data
end

return DataSaver

Any help would be appreciated, thanks!

1 Like

pretty sure this is just a studio error, try going into the actual game and see if anything saves

You are probably saving too many methods at once, try fewer.

Yeah, but how would I do this, I don’t really know how to send fewer request

Not sure, try temporarily removing some values and see if the issue persists.

Instead of making multiple save requests for each different value, you should group all the values in just one table and just use one save request. Same can be done for fetching data too. There is a limit to how many datastore requests you can send in one minute per server.

That’s what I’m doing, aren’t it?

		for _, Index in pairs(Binds:GetChildren()) do
			if Index:IsA("Folder") then
				Keys[Index.Name] = {}

				for i, values in pairs(Index:GetChildren()) do
					if values:IsA("StringValue") then
						Keys[Index.Name][values.Name] = values.Value


						DataModule.SaveData(DataKey, BindDataStore, Keys)
					end
				end
			end
	end

No you’re creating a table for each piece of data. Use table.insert(t, value) to insert each value into an already existing table.

Yes, but you need to move the

DataModule.SaveData(DataKey, BindDataStore, Keys)

outside the loop, because right now your script is bassically making a datastore call for each value you interate over.

Try

game:GetService("Players").PlayerRemoving:Connect(function(Player)
	pcall(function()
	local DataKey = Player.UserId.."-save"

	local Binds = Player:WaitForChild("Keybinds")
	local Keys = {}

	for _, Index in pairs(Binds:GetChildren()) do
		if Index:IsA("Folder") then
			Keys[Index.Name] = {}

			for i, values in pairs(Index:GetChildren()) do
					if values:IsA("StringValue") then
				
					Keys[Index.Name][values.Name] = values.Value
                  DataModule.SaveData(DataKey, BindDataStore, Keys)
				end
			end
		end
	end
    DataModule.SaveData(DataKey, BindDataStore, Keys)
	end)
end)