Is this an effective way of using UpdateAsync?

Hey! This is pretty much my first time using UpdateAsync.
Is this the right way to do it? It works.

CashDataStore:UpdateAsync(key, function()
       return player:WaitForChild("leaderstats"):WaitForChild("Cash").Value
end)

Notice how I didn’t use the oldValue parameter. Idk if I should just set it to the new value, something like

CashDataStore:UpdateAsync(key, function(oldValue)
       oldValue = player:WaitForChild("leaderstats"):WaitForChild("Cash").Value
       return oldValue
end)

Or if that would make no sense.

Thank you!

Definitely read through the wiki page on data stores. Do it once in a while, because some things will only really make sense as you get a bit more experience.


It doesn’t matter if you “use” the oldValue parameter. You’re not actually using it in either example, because the return value never depends on oldValue and it’s not used in any other ways.

Here are some ways you can "use" the variable:
CashDataStore:UpdateAsync(key, function(oldValue)
       oldValue = oldValue + player:WaitForChild("leaderstats"):WaitForChild("Cash").Value
       return oldValue
end)
local daValue
CashDataStore:UpdateAsync(key, function(oldValue)
       daValue = oldValue
       return player:WaitForChild("leaderstats"):WaitForChild("Cash").Value
end)
CashDataStore:UpdateAsync(key, function(oldValue)
       oldValue.someFunctionInATable()
end)

You have one thing that's just plain wrong no matter what:

“The function you define as the second parameter of UpdateAsync() cannot yield, so do not include calls like wait().”
- GlobalDataStore | Documentation - Roblox Creator Hub

You got two WaitForChild calls:

“Returns the child of the Instance with the given name. If the child does not exist, it will yield the current thread until it does.”
- Instance | Documentation - Roblox Creator Hub

WaitForChild is potentially yielding, functions passed to UpdateAsync aren’t allowed to yield. Don’t know what happens if it does, try it with a plain wait() if you’re curious.


Using UpdateAsync without actually using the old value is perfectly fine, if you specifically want to read from the data stores without getting a cached value

“This function caches for about 4 seconds, so you cannot be sure that it returns the current value saved on the Roblox servers.”
- GlobalDataStore | Documentation - Roblox Creator Hub

The wiki page on UpdateAsync doesn’t actually say that UpdateAsync doesn’t pass the cached value as oldValue, but it’s covered on the page for SetAsync:

“If the previous value of the key is important, use UpdateAsync() instead. Using GetAsync() to retrieve a value and then setting the key with SetAsync() is risky because GetAsync() sometimes returns cached data and other game servers may have modified the key.”
- GlobalDataStore | Documentation - Roblox Creator Hub

However, that’s not what you’re doing in your example code. Since you’re not using the oldValue for anything, just using SetAsync would have the exact same effect. AFAIK it’s not an issue to use UpdateAsync when SetAsync would technically do, because the rate limits are shared between the two.

If it’s fine to use the cached version of data for something tho, it’s a good idea to use GetAsync instead of using UpdateAsync to write oldValue to a variable and get the un-cached data that way, because GetAsync has its own rate limits that aren’t shared with the writing methods. I.e. using GetAsync when you can leaves you with more UpdateAsync and SetAsync calls per minute.

Documentation - Roblox Creator Hub

E.g. you might write a function for getting uncached data like so:

local function getAsyncUncached(dataStore, key)
	local returnValue
	
	dataStore:UpdateAsync(function(currentValue)
		returnValue = currentValue
		return currentValue --Return the currentValue to avoid changing it
	end)

	return returnValue
end

But you should only use it when only the uncached version of data will do.

2 Likes