Do you use SetAsync or UdateAsync when changing player data?

I’m currently in the process of setting up my latest datastore. I was just wondering, what would you recommend to save player data: SetAsync or UpdateAsync? In the past, I’ve always used SetAsync, however the wiki recommends the latter:

Also, in what situations can SetAsync cause serious data saving problems, and when is UpdateAsync always the better option?

UpdateAsync ensures the old value, I believe. Something like that?

UpdateAsync is the one to use. It will compare to make sure that the data hasn’t been changed while you were in the process of setting it, and in that event, it will retry given the latest value that is currently saved.

SetAsync is for data that you want to force to be clobbered.

An example of UpdateAsync doing it’s magic:
Datastore: x = 0
GameserverA and GameserverB simultaneously: use UpdateAsync() to add 10 to x
Datastore: x = 20

An example of SetAsync doing it’s set overwrite:
Datastore: x = 0
Game Server A and Game Server B simultaneously: newX = x+10 (result newX = 10)
Game Server A and Game Server B simultaneously: use SetAsync() to set x to newX
Datastore: x = 10

1 Like

It says to use ‘UpdateAsync’ in all situations where two servers may over-ride the data. Does this happen when a player switches servers quickly?

That or when updating a player’s data from another server for whatever reason.

You need to look out with saving data from other servers if you save a local copy of the data when the player first joins. You may override data even when you use UpdateAsync.

1 Like

Yep, I make sure to set their data to nil as soon as they leave
image

What should you be checking with UpdateAsync? All my values are stored in a list, so it’s not as simple to check every bit of data.

You don’t need to do that if your key is the Player object. If the player were to join back, they’d have a different Player object.

Also, what do you mean by what should you check? Just use UpdateAsync instead of SetAsync unless you want to force a set.

(Also don’t use :remove() or :Remove())

UpdateAsync is more reliable to use.

I learned data stores with :SetAsync(), been using it for over a year now and have had many issues with it (data loss / overwrites). I highly recommend using UpdateAsync. My friend, mightybaseplate, uses it for counter blox’s skin saving and we haven’t had any issues with data loss.

4 Likes

Use UpdateAsync. Every time you save, ensure that the data you are saving is not overwriting old data. A good way to ensure you aren’t overwriting old data is putting a counter in user data that is incremented every time you save. If the data you are about to save has a lower counter than existing data, you have a problem and saving would erase the player’s existing data.

7 Likes

I’m using the Timestamp-Save approach for my current project (OrderedDataStore of timestamps → DataStore of save data), so SetAsync.

1 Like

That’s a smart way of approaching it, any downsides to it?

Only really feasible if you can fit all of your player associated data into a single data store key per player.

Trying to use that approach with multiple data store keys would get hairy really fast because it would be easy to get into an inconsistent state. Even with just a single key it took me a couple hundred lines to write a really bulletproof implementation of it. You also inherently use double the datastore requests because you have to update the data table and timestamp table on each save, so if you’re already riding on the limit it might not be an option.

3 Likes

Nice idea, I think Ill give that a try

1 Like