DataStores have limits and you should not be saving data each time a value changes.
Try saving on PlayerRemoving and game:BindToClose()
Here’s a good post by @sjr04 about when to save data.
Edit :
@Winky_y
No, in case of DataStore errors or poor connectivity, requests to DataStores can fail; that’s the reason wrapping them in protected calls is ideal for preventing Data loss, you can use them to retry saving data if an error was encountered.
I just want to clarify that if a player’s data is having errors saving you shouldn’t just keep retrying to infinite times. It’s best to only retry up to 5 times because then you end up running into DataStore limits and more than just one player will be losing data. If you want to get advanced you could use external programs to store/track failed save data.
Alright, so you have to understand that DataStore have a limit on how many times it can save some data.
It is recommended that you save the data each 5 minutes, when big actions are done(like removing or adding a huge amount of money, etc), and when the player leaves. You should also use game:BindToClose! game:BindToClose is just when the server shutdowns. Also, try to use UpdateAsync over SetAsync! I suggest you loop up some tutorials to make sure you used those events correctly.
You should auto save data for all players at regular intervals too, this can prevent potential errors while saving data at other places such as PlayerRemoving.
It really depends on what you are saving and some errors could come up. If it is just the money/points, then sure we could save only when there is a change to those value, but some errors might pop-up. But if it would be some other values that would change in 5 seconds (like a Simulator with a map saving), then saving each 5 minutes would be better than saving each time a part is added.
Its always better to be safe than sorry as it is not really funny loosing some data.
Keep in mind that you only have 30 seconds with game:BindToClose(), so you shouldn’t rely on that heavily if you have a lot of data to save. Saving at regular intervals, when a player leaves, OR on BindToClose (if either of those 2 fail) is the best way to do it imo.
Update gives you the current table through an argument in it’s function so you can use that to “update” the value instead of reset it to something else.
local success, result = = pcall(function()
playerStore:UpdateAsync(player.UserId, function(currentData)
local data = currentData or {}
data[key] = newValue
return data
end)
end)
This is handy if you only need to save on value in a table that’s being saved, and you don’t have the current table handy. It prevents you from having to do GetAsync() to get the table and then set it using SetAsync().