Player UserId as Scope vs Key in Data Stores

I am currently making my data store for my game, and there are some conflicting options. On the Roblox API site, it uses the player.UserId as the scope in:

DataStoreService:GetDataStore(name, scope)

However, I’ve always used the Player.UserId as the key to access stuff within such a scope. Which returns me a table of data.

So for example:

local lvls = DataStoreService:GetDataStore("Version1", "Levels/Experience")
local l = lvls:GetAsync(plr.UserId)
plr.leaderstats.Level.Value = l["Level"]
plr.leaderstats.Exp.Value = l["Experience"]

That is what I do.

But Roblox API does:

local function onPlayerAdded(player)
	local scope = "Player_" .. player.UserId
	local playerStats = DataStoreService:GetDataStore("Stats", scope)
	local playerResources = DataStoreService:GetDataStore("Resources", scope)
end

My question is: What is the more efficient/faster method of using data stores? Using the UserId as the key or as the scope?

Note: I realize this might be dependent on scripter’s structuring of the data store.

4 Likes

Changing the scope (internally) makes a new datastore. You shouldn’t have player-specific datastores or scopes.

This is because datastores are cached under the DataStoreService for the lifetime of the game server (and cannot be removed from said cache). This means that having a number of unique players will be detrimental to the performance of your game.

You really should use keys and store all the data in a table, under said key.

7 Likes

I agree with what ElliottLMz said - using scopes adds to the number of datastores. Stick with one key as you are already doing, and you can much easily get the data from the table you use, change it easily and reorganize it as you like.

However, I would like to know what the purpose of RemoveAsync is if it’s purpose is to remove a data store? Is it not removing the cache? The wiki doesn’t get into the specifics, so I was curious after reading this thread.

It removes data from the specific store. My point is that the datastore itself (not the keys, etc within it) are cached.

Datastore key/value pairs are not cached, but datastores are.

Just using GetDataStore can inhibit performance issues alone.

This graph from buildthomas may help:

1 Like

I see, thanks for clarifying, that graph is a good aid as well.

I’m confused then, as to why the Roblox API recommends (or at least shows) using the player user id as the scope. This could instigate bad habits in new scripters. Is the page an old one?

Do you have a link to a page on the DevHub that suggests this?

Here, this is what got me confused originally.

1 Like