DataStore Limits

I’m working on saving data to my game, and I was wondering what is the best way to save the data,
should I use one datastore for all the player’s data or should I use more than one datastore?

and if I used more than one datastore is there a limit of how many datastores can I use?

should I do it like this?

local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerData")
 
-- Table to hold player information for the current session
local sessionData = {}
 
-- Function to add player to the "sessionData" table
local function setupPlayerData(player)
	local playerUserId = "Player_" .. player.UserId
	local data = playerData:GetAsync(playerUserId)
	if data then
		-- Data exists for this player
		sessionData[playerUserId] = data
	else
		-- Data store is working, but no current data for this player
		sessionData[playerUserId] = {
			Exp = 0
			,currentWear={Shirt = 0, weapon = 0}
                        , Inventory = {...}}
	end
end

local function savePlayerData(playerUserId)
	if sessionData[playerUserId] then
		playerData:SetAsync(playerUserId, sessionData[playerUserId])
	end
end

or should I do it like this?

local DataStoreService = game:GetService("DataStoreService")
local playerInventory = DataStoreService:GetDataStore("Inventory")
local playerEquipment = DataStoreService:GetDataStore("Equipment")
local playerData = DataStoreService:GetDataStore("PlayerData")

--and then save each data separately
3 Likes

The issue isn’t whether there are limits to the number of datastores, but the issue is with the limit of the GET and SET functions (found here)

If you have multiple datastores, you will need to make multiple set/get calls to each datastore for each player and will quickly reach the limit.

Instead, you should save tables of data to the datastore, e.g. a dict:

local DATA_TEMPLATE = {
	UserId = 0;
	Inventory = {
		{Name = 'Sword'; Rarity = 5};
		{Name = 'Water bottle'; Count = 5};
	};
	Equipment = {
		LeftArm = ; --blahblah
	};
	Cash = 500;
}
4 Likes

It’s a design choice.

There’s no limit on how many DataStores can be created. However, there is a limit on how much data can be stored per entry (For every player) under each separate DataStore.

P.S, DataStores are saved as strings. You can use a JSONEncode() function to check the lengths of DataStores. Read about Data Store Errors And Limits.

3 Likes

there is a lot of data that I want to save for each player, I’m afraid that saving all the data in one table will reach the limit of the stored data per entry

will this be a problem?

Unless your saving around 200 lines of data, you should be fine. use 1 table and use JsonEncode to encode it into a string then save it. Its what i done for an object serializer and save test. I’ve never had an issue with it.

1 Like

How much data are we talking? What kind of game? Need a little more detail, I can suggest other options if you think it’ll truly surpass the 260k character limit.

Your example above just describes exp/inventory/equipment which to me would usually mean it’s an RPG/Shooter etc - although it seems like a lot of data, it usually isn’t. You can drastically reduce this type of data too, because you know that user will only have assets that have been prebaked by yourself. That means you can serialise the data e.g. for the inventory to save on characters for the names of items the user has:


local itemEnum = {
	['Sword'] = 1;
	['Water bottle'] = 5;
}

local function serialise(data)
	-- need to deepclone the data if this is cached data you're sending
	local new = { }
	for key, item in next, data.inventory do
		new[key] = itemEnum[item.Name] --> Assuming you don't need to save the 'rarity' etc
	end
	
	data.inventory = key
	
	return data
end

local function deserialise(data)
	local function get(i)
		for j, k in next, itemEnum do
			if k == i then
				return j
			end
		end
	end
	
	local new = { }
	for key, item in next, data.inventory do
		local name = get(item)
		if name then
			local item_info = game:GetService('ReplicatedStorage').SomeItemFolderWithInfo:FindFirstChild(name)
			if item_info then -- now let's get that other data back from our prebaked assets
				new[key] = {Name = name; Class = item_info.Class.Value; Rarity = item_info.Rarity.Value}
			end
		end
	end
	
	data.inventory = new
	
	return data
end

Similarly, for RPG/Shooter games, you normally don’t have to save things such as the weapon level unless you have a weapon levelling system - all of the damage etc is done by calculating the base damage of the sword * the character level + any bonuses etc.

2 Likes

I did this before i utilized JsonEncode and JsonDecode so it keeps it in a dictionary format.
So it would look like this

local t = {
      ["KeyBind1"] = "E"
}

I save the key Binds like this and assign it after JsonDecoding it.
Why do you need to JsonEncode because Data Stores only take valid UTF -8 chars

1 Like

does per entry means that for every value in the datastore i have 260K characters ???

Yes, per key you have 260k characters. e.g. when you set a player’s data to a key with the key as their UserId, you will get 260k characters to set as the value

3 Likes