:GetNameFromUserIdAsync() request limits?

In my game there is 2 global leaderboards that use the player’s user id as the key to the OrderedDataStore. The server will send the data of the OrderedDataStore to the client and the client will loop through the data and display it accordingly on the leaderboards. But because the key is the player’s user id I have to use :GetNameFromUserIdAsync() to get the player’s name but eventually the request returns a HTTP 429 (Too many requests) error.

How can I get around this error? For context, each leaderboard displays 100 players and the leaderboards are updated every 2 minutes. That means that all clients in the game (maximum 40) will make 200 of these requests every 2 minutes but I don’t know if each request counts toward a total number of requests the entire game can make or if it counts towards a number of requests each client can make, so is it 200 requests per minute per player? Or 1000 total requests the game can make every minute?

Here’s the code on the client:

Remotes.RemoteEvents.ServerToClient.UpdateGlobalLeaderboards.OnClientEvent:Connect(function(TotalDistancePage, DistanceWalkedPage)
	if TotalDistanceLoading or DistanceWalkedLoading then return end
	
	TotalDistanceLoading = true
	DistanceWalkedLoading = true
	
	for _, Frame in ipairs(DistanceHolder:GetChildren()) do
		if Frame:IsA("Frame") then
			Frame:Destroy()
		end
	end
	
	for _, Frame in ipairs(DistanceWalkedHolder:GetChildren()) do
		if Frame:IsA("Frame") then
			Frame:Destroy()
		end
	end
	
	coroutine.wrap(function()
		for Rank, SavedData in pairs(TotalDistancePage) do
			local Username = game.Players:GetNameFromUserIdAsync(tonumber(SavedData.key))
			local Distance = SavedData.value

			local Sample = script.Sample:Clone()
			Sample.DistanceLabel.Text = Distance
			Sample.PlayerNameLabel.Text = Username
			Sample.RankLabel.Text = "#" .. Rank

			Sample.Parent = DistanceHolder
		end
		TotalDistanceLoading = false
	end)()
	
	coroutine.wrap(function()
		for Rank, SavedData in pairs(DistanceWalkedPage) do
			local Username = game.Players:GetNameFromUserIdAsync(tonumber(SavedData.key))
			local Distance = SavedData.value

			local Sample = script.Sample:Clone()
			Sample.DistanceLabel.Text = Distance
			Sample.PlayerNameLabel.Text = Username
			Sample.RankLabel.Text = "#" .. Rank

			Sample.Parent = DistanceWalkedHolder
		end
		DistanceWalkedLoading = false
	end)()
end)

I think the best approach would be to use a cache. When you loop through the data, you can store the username from :GetNameFromUserIdAsync() to the cache, and next time you want to grab the name of a userid, you dont have to call the function again because its stored in the cache. Do that on the server, and then the server can send this data to the clients

4 Likes