You’re using SetAsync which has no regard for previous data.
Imagine a scenario:
- Player joins server A
- Server A loads player’s data
- Player’s data changes in that server
- Player leaves Server A, triggering a save
- Server A starts saving Player’s data, but it is taking some time
- Before Server A finishes saving the Player’s data, Player joins a new server: Server B
- Server B loads player’s data which is the not-yet-updated copy of it
- Server A finally finishes saving, updating the data but it’s too late because Server B already loaded outdated data
- Player leaves server B because they see they lost data, triggering a save
- Server B saves their oudated copy of the data, overwriting the newer data that Server A had saved with outdated data
The remedy to this is using Session locking. I found a community tutorial for it here: Session locking explained (Datastore)
But other community modules like ProfileService handle this out of the box if you want a ready-made solution.