I’m recreating Infinite Craft in Roblox and hitting DataStore request limits with just 3 players. Need advice on optimization.
Current Implementation:
- Using DataStore to save:
- Global combinations (saved on each new discovery + auto-save every 5min)
- Emoji mappings (checked/saved for each new element)
- Element combinations store (checked for each combination attempt)
The Issue:
With just 3 players actively combining elements, we’re hitting DataStore request limits. Each combination attempt requires multiple DataStore interactions:
- Checking if combination exists
- Saving new combinations
- Checking/saving emoji mappings
- Plus periodic auto-saves of the global state
Current Rate Limiting:
- 450 requests/minute per server
- 32 requests/minute per player
Even with these limits in place, we’re still hitting DataStore caps. Has anyone solved similar high-frequency DataStore usage issues?
What We’ve Considered:
- Batch Updates:
- Could collect changes and save less frequently
- BUT: Other servers need to know about new combinations immediately
- Problem remains: How do servers stay in sync with delayed saves?
- MemoryStore as Buffer:
- Could use MemoryStore for temporary storage
- BUT: Still need DataStore for persistence
- Doesn’t reduce the fundamental number of operations needed
is every combination saved on a module script/manually made or is it like automatically generated?
The combinations are automatically generated using the Gemini AI API:
- When players try to combine elements, the system:
- First checks if this combination already exists (saved in DataStore)
- If it exists, returns the saved result
- If it’s new, calls the AI to generate a result
- The AI generation happens in two steps:
- First generates a word result (like “steam” from “water + fire”)
- Then generates an emoji to go with it (like “
”)
- Combines them into “
Steam”
- Storage:
- All successful combinations are saved to DataStore
- Emoji mappings are saved separately to ensure consistency
- These saved combinations become the “global discoveries”
maybe instead of saving the emoji, just generate the emoji each time they join
i don’t know if it would be unoptimized since i have never used it
Bumpity Bump! Need help! Still don’t know where to go form here.
I assume the issue here is you are requesting GetAsync and SetAsync too fast which quickly builds up rate limits (60 + 10 * (player count)), instead of creating multiple keys for each discovery, you can try creating a key for a player (ex. “Player_” … UserID) and loading this key whenever the player first joins the game. You can make changes to this key (assuming it is a table) and save it whenever the player is leaving.
I suggest using ProfileService for this as it is a great module for managing datastores.
The problem isn’t with player data saves/loads (which your solution would help with). The issue is with the global combinations system:
When any player anywhere combines “Water + Fire”:
- We need to check if this combination exists globally
- If it’s new, we save it so ALL players across ALL servers know about it
- Other players need to know about new combinations in real-time(ish)
So while ProfileService is great for player data, it doesn’t solve our main problem:
- Server A’s player discovers “Water + Fire = Steam”
- Server B’s player tries “Water + Fire” right after
- Server B needs to return “Steam” too, not generate a new result
We’re hitting limits because:
- Every combination attempt needs to check global combinations
- New discoveries need to be immediately available to all servers
- Multiple servers accessing/writing to the same global combination table
Maybe try using MessagingService.
I have tried doing a pet exist system like this once: Public Data Saving
You could look into the scripts, i used datastoreservice with :UpdateASync()
With UpdateAsync you could check if a value exists + directly overwrite it.
And for MessagingService. I used it to tell every server that a new value has been insterted/updated.
This module has been made in 2024 Juli, so dont expect much of it, but maybe the technique will help. I hope this helps! ^^
Sorry for the previous reply, I believe the only way you can do this is to implement rate limits (ex. allow 1 combination to be made every second (which wouldn’t make much of a difference if players arent constantly spamming), if the user is attempting to make a combination but there is still a rate limit it will wait until the rate limit is complete and reject new combinations until the current task is done.)
- Yes you can use batching for this but if the server crashes the data would be lost.
- You can also use MemoryStores for temporary cache, but if all servers are down the data would be lost again.
- Another option would be MessagingService, but if player 1 rejoins while player 2 is still on que they will still reclaim it since the data from MessagingService wasn’t recieved.
I suggest making the game singeplayer and implementing a global chat system, this way you can maximize rate limits.