A lot of people have made posts on how to convert their systems to use UpdateAsync because UpdateAsync is better according to this post by @ForeverHD.
This post has a lot of already existing opinions and it does share a lot of what I am gonna say, however I’ll try packing in more updated and more specific details.
What is different with :UpdateAsync?
First of all, UpdateAsync will try to re-run calls if the set call is done after another set call happened, until every UpdateAsync call was done in order.
UpdateAsync is a smart Get-Set combo as stated by colbert in the replies of FHD’s topic.
A UpdateAsync call will accept a key, and a function.
This function will be ran with the first argument being the data that is currently there, you can use that data for comparation, getting data from it… etc.
Example:
ds:UpdateAsync("userId", function(pastData)
-- compare past data, get stuff from it, etc.
end)
From this call, you have to return back the data you wanna save, in case you return nil, it will keep the data as is, and not save and not do any write requests.
Another example:
local newData = {
Cash = 100;
}
DataStore:UpdateAsync(player.UserId, function(pastData)
return newData
end)
It will now save the new data, yes!
…but it doesn’t seem to do much different.
What should I use UpdateAsync with?
If you didn’t notice already, you should be saving data with tables and making everything save under one key, if it’s related data. If you’re not doing that, learn how to do that before thing to understand this. UpdateAsync has no use for people who save data separately.
UpdateAsync, should be used to compare data, and decide if it should be overwrite it or not.
A simple example, but pretty good and popular example is to compare version numbers.
An example would be:
ds:UpdateAsync(key, function(pastData)
if pastData.DataVersion ~= player.DataVersion.Value then
return nil --// Cancels saving data, doesn't do a write request.
end
return {
--// Data is safe to overwrite!
DataVersion = player.DataVersion.Value + 1
}
end)
This example is showing how you should keep a number which increases every save.
This number gets compared when trying to save, it needs to be the save as the number we got when we loaded data.
If it isn’t the same, don’t try saving any new data. Cancel that!
This example prevents trying to write data twice (overwriting).
This tecnic is popular and you should use it in your data saving system if UpdateAsync calls are being used!
There’s also tecnics like session locking, which use UpdateAsync in everything to achieve their effect, it’s something that’s really nice to look into.
When should I not use UpdateAsync?
This is pretty simple.
- If you have anything that Is only ever written to once, and that overwriting doesn’t matter
- Leaderboards (the same for any OrderedDataStore use)
- Just data that doesn’t overall matter.
If you’re using leaderboards, PLEASE DON’T USE UPDATEASYNC.
I would like to point that out because I see so many people blindly recommending using UpdateAsync in everything for no reason.
Leaderboards only mimic data! You should never care about data loss in a leaderboard anyway. Ordered DataStores can only save numbers anyway! You’re not even comparing ANYTHING.
Don’t use UpdateAsync calls for things that are supposed to be written to only once.
If you’re saving data that isn’t a table anyway, for the most part, you’re not able to compare data, therefore UpdateAsync turns useless.
Additional info:
- Don’t yield (task.wait, Async calls, etc) inside UpdateAsync functions.
- Try comparing the most facts about data you can, things that wouldn’t cause an issue comparing, but would if something’s wrong.