Serialized value exceeds 4MB limit

I’m making another r/place game on roblox, Im trying to get a 1000x1000 grid, my issue is, I get this error when I try and save data for 1 million pixels,

"Serialized value exceeds 4MB limit."

I tried encoding and decoding it with json to try and compress the data but it yields the same result
Is it possible to go past this value, and/or bypass it?

the data I’m saving looks like this

ds:GetAsync('Grid')['x,y'] = { -- x,y being the pixel location
    Color = Color,
    Player = Player, 
    LastPlayer = Player, 
    LastColor = Color

200x200 grid works as normal, 300x300 already yeilds this result

maybe try making a different key for each pixel? like this:

ds:GetAsync('x,y') = { -- x,y being the pixel location
    Color = Color,
    Player = Player, 
    LastPlayer = Player, 
    LastColor = Color

Roblox Datastores have quite a few limits, so this would be difficult to do for every server startup.

Apparently for each key value you can have up to 3 million characters, and there’s a 6 second cooldown between Set requests. There’s no written cooldown for Get, so maybe you could somehow split all the data between a few keys instead of a key for each pixel.

Suphi Kaner has an awesome video based on reducing the amount of characters in a key inside a datastore using Json. Compress / Optimize Datastore - Roblox Scripting Tutorial - YouTube

1 Like

Using binary can save on space, but you’re trying to save a lot of data here.

What’s the purpose in storing the previous player & color? Wouldn’t storing the current player’s user ID and current color for each pixel suffice? This will halve the current amount of memory you’re utilising. Additionally you should round the color channels of Color3 values, i.e;, 0.123456789, 0.123456789) would be stored as, 0.12, 0.12).

local Pixel = {
	ID = Player.UserId,
	Color = {
		R = 1,
		G = 1,
		B = 1

For further memory optimisation you could store player IDs in a base greater than 10 (decimal), for example 16 (hexadecimal).

its made for moderation purposes (an example would be reverting the color back because of an exploiter/troll)

I will be watching this, thank you!

I would suggest saving the data like this

ds:GetAsync('Grid')['x,y'] = "R%G%B|Name|Name|R%G%B"

This is some basic sterilization which converts colors and the names to one string, after that you can make a decompiler to convert the strings to its corresponding values. (that still takes around 60 bytes per node)

Also sterilizing data here isn’t really an option (you can max save 4 bytes per node)
Here are some options:

  • Make the grid smaller (500x500 for example)
  • Separate the data in chunks (have for example 4 data stores for the grid)
  • Save less data (only the color for example)
  • Use your own data store ([Open Source] FirebaseService)
1 Like

Fair enough, as a fallback you could just reset the pixel entirely.