How should I save player data?

For context I’ve made many different datastores for many different games in the past and I’ve never had any issues, but now I’m working on a very large project where data is quite literally the most important thing (trading is involved).

I know some datastore methods such as UpdateAsync, game:BindToClose() saving, data keys, scopes.

Though I don’t know what “method” is best for saving data, should it be one data store in a table, one data store using scopes, multiple data stores with or without scopes? Or should I spend the time to invest in a prebuilt datastore like ProfileService or Datastore2?


Most users do not use that, so I would recommend not using it!

It mainly depends on the type of project you are wanting to make. I would be more than happy to give you my module I wrote for game development w/ databases :slight_smile:

Is there a problem with using UpdateAsync or game:BindToClose()? I never found issues with either.

I was using ProfileService since the progammers on this team before me were using it, but its proven difficult for me since I’ve always written my own datastores, but if its better at saving data in any way I am interested in using it.

game:BindToClose() isn’t bad but its much easier to loop over and save using a pre-written function.

function save(Player: Player)
	-- Code for function

	for i,v in pairs(game.Players:GetPlayers()) do

I personally like to use a module (which I can give you if you’d like), that has all the functions needed for the database. It comes complete with all fully written and optimized functions.

Similarly, I use my module to be heavily optimized and designed to use. It comes complete with loading, saving, reconciliation, altering data, game closing, and auto-saving, + administrative commands (as needed).

Using the module can work similarly to this:

local Players = game:GetService("Players")

local DS_Handler = require(

Players.PlayerAdded:Connect(function(Player: Player)
	-- Load Data --
	-- ALter Data --
	DS_Handler:AlterData(Player, {
		["Coins"] = 100 -- Changes the player's coins to 100
		-- Others -- 

Players.PlayerRemoving:Connect(function(Player: Player)
	-- Save Data ---

To add the player’s template data all you need to do is go into the module and add the player’s data!

local PlayerData = {
	["Coins"] = 0

return PlayerData

If done correctly, it works super simple and is heavily optimized (shows data working below!)


In The DB:

Let me know if you have any questions! :grin:

I’d like to take a look at your system because I’ve programmed all these features but (comparing to profile service) my script seems too short. Again, my team and I haven’t found an issue with the datastore I made so far but this game is being endorsed by youtubers and I don’t feel like being clowned on for having bad datastores

Yeah, sure, shoot me a dm and I can help you set it up and let you see it.

Something I add that is quite unique (i doubt lol) is that I run to a backup database as-well, in the case of something happens to the live database, I auto-save to the backup DB as well.

If you don’t mind, can I check out the project you are referring to?

Also (if you know) how good is datastore2 and profileservice? Throughout the community most people either love it or hate it, and I don’t get why.

I was thinking about making a backup database, but I don’t know how useful it would actually be (assuming that most games do fine without it).

The project isn’t out yet but we have a discord server

Yeah, shoot me a dm @coder_dog!

A bit of a small correction in your BindToClose snippet, you should probably use task.spawn(save, v) since you should save the data as fast as possible

You’re right! Thanks man!