Hello! My question here is simple-- is Datastore2 or ProfileService excessive for what I want to achieve?
Basically, the only thing I’m really gonna be saving are things like a player’s currency, inventory, and what quests they’ve completed. Would just using UpdateAsync() be good enough for something like this while preventing dataloss?
If UpdateAsync() suffices, then what would be the best way of saving with it? Should I put all the data under 1 key, or have separate keys per player?
Thanks if you take the time to read this and reply!
ProfileService is definitely recommended to use over DataStore (most of the time), it has auto-saving and generally straightforward.
As for UpdateAsync vs SetAsync, UpdateAsync is safe, slower, has a limit and retains past versions of data, while SetAsync is faster but riskier and doesn’t have a limit. You should use multiple keys for each player since their data is unique to them.
In my post I answered both your queries. To summarise:
I recommended you to use ProfileService for most data-saving matters but if you arrive at a situation in the future where you need to use Roblox DataStore, you can use SetAsync or UpdateAsync according to what y suits you
it’s not necessary, but profileservice offers useful necessary features that standard datastore doesnt, such as anti dupe session-locking.
this combined with the incredible optimization makes it a top choice for data saving, just saves you a lot of time
I personally always use ProfileService, I hate Roblox’s datastores, and ProfileService makes it easy with simple, modular functions. ProfileService uses basically every method to fix duplication glitches, data loss, corruption etc.
But it really depends on what you want to do! I would recommend it though, especially since you are saving inventories (which profileservice is best at, imo). Theres really no good reason not to use it.
If your confused or need help on how to use profile service, this tutorial by dot product is great.
I don’t see why using Datastore2 or ProfileService could be considered excessive in any type of game. If it means saving time by not having to write your own data storage infrastructure, go for it. Both modules also offer a plethora of features that are really useful; most notably session locking.
You all had really great responses, it’s hard to mark just one as the solution lol. The only reason I questioned whether it was excessive or not is because I was really overthinking the best way to save data, because I have been using the same script over and over to save data in my games.
Yes it’s excessive for basic data. Can maybe be helpful if you need session lock, but that’s simple enough to implement on your own.
ProfileService is an absolute nightmare in production (I’ve used it on multiple games with ~40m combined sessions this year). For some reason it takes forever to do the initial data load, forcing you to reach for annoying patterns like chaining events down from PlayerAdded, or wrapping literally everything in promises.
It has proven to constantly just fail to load anything at all, returning nil from ProfileStore:LoadProfileAsync(), without logging any errors, warnings, or providing any mechanism for retries. You end up having to wrap it in your own data library just to do the things you’d reach for a library to do.
The session lock can randomly bug out, forcing you to manually reset a players lock by hand so they aren’t kicked upon joining your game. This problem is exacerbated when testing with API enabled in studio; it’s essentially a 100% guarantee you’ll be locked out.
It doesn’t bother to do any serialization at all on save, forcing you to constantly reimplement the same wheel over again just to save very straight forward things like Vector3’s.
Pairing it with ReplicaStore as intended becomes an even worse nightmare. State comparison is shallow, meaning you’re either forced into 1 giant top level data table, or stuck firing your own events. Sometimes updating the Replica’s data will cause it to be saved in ProfileStore, other times it just wont, and the documentation doesn’t offer much help as to when that is.
Edit, adding some logs that have kicked in the past hour in a game with 90CCU.
It’s nice to see criticism of it, because I’ve only seen people praising it so far. Duplication isn’t a worry for me as the inventory items are not tradeable and provide literally no benefit if you have more than 1. Some of them will be pretty rare (and some payed), so I really want to make sure there’s no data loss.
Yeah you’re welcome! I’ve always heard nothing but praise; it’s always everyone’s top recommendation. I’m wondering if it’s just not wildly used at scale. The day or two I could have spent writing my own reusable DS library would have saved me literal weeks of headaches down the line, but it wasn’t my choice to use it or not.
As far as DataStore2 goes; there’s absolutely no reason to use it anymore. It existed to provide data versioning support by spamming new keys instead of overwriting/updating existing ones. Roblox has built in versioning now so that’s entirely useless, and just makes it infinitely more difficult ifwhen you need to work with your data directly via the plugin or Open Cloud.
Personally, for something so critical like datastores, I find that using other modules that have been tested in many people’s games is important; you can’t get this sort of testing otherwise. However, I am not a fan of Datastore2 or ProfileService with Datastore2 being outdated with its versioning system and ProfileService having issues with session locking. There is also a lot of bloat in both of these modules that could be avoided when looking into them.
I would suggest building your own module; however, I realize that takes a lot of time, and any sort of bug could lead to massive complications in your game. I thought about doing this myself when I found a module that is talked about less but solves the problems mentioned about ProfileService.
I have used this with my new projects, and it’s called Suphi’s DataStore. Not only does the creator do a great job of explaining the benefits of his datastore, it’s easy to use and contains a lot less bloat. It uses a memory store for session locking which does not waste the limits of your datastores, and has its own expiry time that the memory store itself will remove the lock instead of depending on time that may not be synced up between servers. It’s the most modern datastore handler I have seen, and I can’t really see where you would run into issues with how its built. If you are building a new project and need good datastore handling, I highly suggest using this!
It does not really matter what data your saving at the end of the day saving data into the datastore will have the same process if its a small amount of data or large amounts of data so picking if you should use a module should not be based on the data your saving
So some reasons you would pick to use a module are
I want to finish the project as quick as possible
I’m still a new scripter and I’m worried that my code will have bugs that causes players to lose data
And some reasons you would not use a module are
I do not care about finishing the project as quick as possible I want to improve my scripting ability
I’m still a new scripter and scripting and debugging will help me improve
I want to design the system to work the way i want and have the features i want