Save your player data with ProfileService! (DataStore Module)

Can you print the profile before it is released and share it here?
Another part of the code must be putting an invalid character in.

I figured it out! My system was somehow adding an instance into the data.

Is it possible for unstated data in Profile Templates to be defaulted to 0, false, etc. values or would I have to state the value for each one?

-- ProfileTemplate table is what empty profiles will default to.
-- Updating the template will not include missing template values
--   in existing player profiles!
local ProfileTemplate = {
    Cash = 0,
    Items = {},
    LogInTimes = 0,

How can I handle teleport failures if I use ListenToHopReady? Do I just use the same function as the PlayerAdded one when the teleport fails?

Hello, i wanna ask if it is safe/possible to modify this module into making it handle third party database like Firebase instead of Roblox datastore? Like only change the parts where it do UpdateAsync, GetDataStore, GetAsync, etc?

Yes it is possible, though highly not recommended because you’ll end up rewriting a lot of ProfileService and DataStoreService is most likely faster than Firebase.

1 Like

How can I turn off auto saving??

I need help understanding this :frowning:

This is probably a silly question but, in the future (like 3+ years) is there a chance this will ever go unsupported/deprecated? I want to use ProfileService for my game but what if Roblox designs something that makes this module become obsolete, forcing me to create a new data system, essentially wiping everyones data?

I do currently have Profile Service running through FireBase, you’ll want to adjust the rate of backup to reduce usage to stay on a free plan, fix the error for Firebase not wanting to save an empty array for GlobalUpdates by faking it or sending 0, and only consider this use for servers with 100 unique players a day at most. Any higher could hit limits to make you have to pay for a paid plan for more limits.

1 Like

There are some tutorials that were referenced in the original post that could help walk you through setting it up. I’d suggest referencing the mini tutorial on ProfileService’s GitHub page and its API on the same GitHub page alongside these video tutorials, too:

Considering loleris mentioned the following:

As long as a combination of any major changes being made to the base DataStore system and loleris deciding to cease development of this module don’t happen, I’d like to infer that there’s a high likelihood that ProfileService continues to work as intended even if it stops receiving timely updates at some point.

For reference, Datastore V2 was recently released and it seemed to focus on providing additional functionality that would work alongside what we already had access to. From what I understand, if that trend continues, ProfileService should be relatively future-proof, even if new built-in methods, functions, etc. aren’t added to this module to make it more intuitive to incorporate into existing systems.

Even if an update came along that made this module obsolete, it shouldn’t wipe any of the existing DataStore keys that have stored player data which means that it should still be able to be recovered by making use of the same keys even if you have to build up a new system for your game.

However, this is just based on my best guess so don’t take my word for it! :wink:


I would personally not exceed 2 profiles per player, though.

Is there a reason for this recommendation? What are the benefits of trying to cram all the user’s data into one key/value pair?
What if I’m concerned about datastore data limits per key value?

Is there a pre-defined way/function of actually connecting a player with a global update on the receiving end? Apart from passing the targets UserId in the global update data and using it to iterate through the server’s current player list, I am not sure how I would go about associating the global update with a specific player.

I watched okeanskiy’s video regarding the topic and their end result was the server receiving and parsing the information, and I was just wondering if there was a built-in function through ProfileService that I am missing that would be better than just passing the UserId as I said before and iterating through the server list.

Right now I’m just using a basic function that gets the player via their UserId that I send along with the data.

-- Localscript
		"Player_".. TargetId,
				updateType = "FriendRequest_Incoming";
				sender = player.UserId;
				target = TargetId;
				sendTime = os.time();
local function getPlayerByUserId(UserId)
	for _, player in pairs(Players:GetPlayers()) do
		if player.UserId == UserId then
			return player

local function handleLockedUpdate(globalUpdates, update)
	local id = update[1]
	local data = update[2]

	if data.updateType == "FriendRequest_Incoming" then
		local TargetPlayer = getPlayerByUserId(
        -- More stuff here but unnecessary to this post
		NewIncomingFriend:FireClient(TargetPlayer ) -- Only alert TargetPlayer's client to ping server for updated infomration.


I suppose ultimately what I’m asking is, is there a more efficient way of doing this without needing to manually send their UserID? I only ask because I’m already targeting them on the sending-end of things by using a profile key with their UserId in it, so I wasn’t sure if I missed a native way of doing this.

1 Like

Rather than iterating over a table of players in the game. You can use game.Players:GetPlayerFromUserId to get the corresponding player object assuming they are in game.

local TargetPlayer = game.Players:GetPlayerFromUserId(

As far as I know, there is no native way to handle GlobalUpdates directly using players and objects instead of a UserId string.

1 Like

I have no idea how I overlooked game.Players:GetPlayerFromUserId. Thank you so much for the reply and your input :open_hands:

1 Like

need help. dm me



I’m having issues with Profile Service, after setting up the data template and everything it works fine… but once the game is played by players and etc, if i added any new value to the data template it returns “nil” and errors until i totally wipe Data, How Can i Solve this issue? Since i can’t really wipe data again to just add a few values…

Look at and use profile:Reconcile() :wink:


Alright Let me read about it, then i will tell you if it worked ;c

Hello, I have a question. When using LoadProfileAsync if the profile isn’t found / there is no saved profile with the key, will it simply just write to the datastore / cache with the key and essentially prevent it returning a non existent profile.

If so how could I circumvent this as i want specific behaviour for when data in that certain key hasn’t been saved before.