I’d recommend using tables only instead of making a new table with values every save, but yeah using BindToClose() to save data on shutdown is a good idea.
Use a dictionary instead, what you’re saving is an array. This will make your data structure incredibly confusing when you load it out especially since you have so many values you’re putting into the table and even of different categories.
Data loss can happen in a number of scenarios so it’s not necessarily guaranteed that BindToClose will prevent data loss - queued requests that don’t complete in the time frame will get dropped and thus data loss - so don’t rely solely on the BindToClose. You should have some autosaving as well. Be mindful that BindToClose functions are only called when the server closes, not crashes.
You might also find it much more sane on maintenance purposes to make saving logic once and then apply that to your autosaving, player leaving and BindToClose rather than doing that work by hand in BindToClose itself. This current pattern you have may make saving logic across the board inconsistent.
As mentioned above I would personally use something like ProfileService instead of implementing this saving logic myself, but if you dont want to do that I would recommend using UpdateAsync() instead of SetAsync(). UpdateAsync(callbackFunction) will connect to a callback function that you provide and will give you the most up to date data in that function, so that you can run extra checks and ensure that what you are saving is correct.