Datastores: reported "UpdateAsync" budget is wrong for OrderedDataStore::UpdateAsync

Due to the fact that Enum.DataStoreRequestType.UpdateAsync budget is determined through the minimum of the GetAsync and SetIncrementAsync budgets (see this thread), this results in the UpdateAsync budget being inaccurate when used in conjunction with OrderedDataStores.

This is because OrderedDataStore::UpdateAsync consumes SetIncrementSortedAsync requests instead of SetIncrementAsync requests, opposed to the regular GlobalDataStore.

How to reproduce:

  1. Open a baseplate and publish it to a place with Studio API access
  2. Run the following code in the command bar:
local ds = game:GetService("DataStoreService")
local ordered = ds:GetOrderedDataStore("Test")

local i = 0

print("draining SetIncrementSortedAsync budget...")
while ds:GetRequestBudgetForRequestType(Enum.DataStoreRequestType.SetIncrementSortedAsync) > 0 do
	ordered:SetAsync("TestKey"..i, i)
	i = i + 1
end
print("drained!")

print("run OrderedDataStore::UpdateAsync loop...")
while ds:GetRequestBudgetForRequestType(Enum.DataStoreRequestType.UpdateAsync) > 0 do
	-- I checked the budget, so this should never throttle, right?
	ordered:UpdateAsync("TestKey"..i, function() return i end)
	i = i + 1
end
  1. Watch output window

Observed behavior:

After a while, warnings start to appear that the OrderedDataStore::UpdateAsync calls were throttled. This is unexpected, because I clearly checked for the budget for UpdateAsync being higher than 0 beforehand!

draining SetIncrementSortedAsync budget...
drained!
run OrderedDataStore::UpdateAsync loop...
18:48:14.651 - Request was throttled. Try sending fewer requests. Key = TestKey62
18:48:16.185 - Request was throttled. Try sending fewer requests. Key = TestKey63
18:48:18.156 - Request was throttled. Try sending fewer requests. Key = TestKey64
18:48:20.135 - Request was throttled. Try sending fewer requests. Key = TestKey65
...

Expected behavior:

I expect that checking the UpdateAsync budget should be correct for OrderedDataStore::UpdateAsync, since the method name is the same as the budget enumerator name, and that enumerator holds for GlobalDataStore::UpdateAsync.

When UpdateAsync budget > 0, I should be able to call OrderedDataStore::UpdateAsync without generating a throttle warning.

Other information:

To fix this bug, it might require shifting the budget checking API onto a new API on GlobalDataStore / OrderedDataStore such that UpdateAsync/other budgets can be checked separately for these two datastore types, since, while the UpdateAsync methods are named the same between the two, they use budgets differently.

1 Like