Item Tracking and Trading - Best Practices?

In many games today you will find player trading to some extent. It could be trading of functional items or cosmetic items; in some cases upgrades or skins carry over, and other times not. Duplication needs to be countered, and with trading also comes the need for tracking and moderation. Having transaction history available is a great tool.

To track items we need to be able to uniquely identify them, but where is the line of data redundance?
Each transaction should probably also have a unique ID, and needs to be tied to the players executing it.
What do you store in the playerData directly, and what do you store in a separate database(/store)?
Is it enough to track only their current items and transactions, or should all their previous items be tracked too?
If you want item upgrades to carry over, just storing the item ID and item type is probably not enough, but having a global datastore of items will quickly exhaust your data budget.

So the question, more defined:
How to design an item system which:

  • Supports item upgrades (carries over)
  • Supports trading
  • Supports moderation actions (viewing transaction history for recovering lost items, revoking scams etc.)
  • Supports multiple items of same type (but uniquely identified)
  • Minimizes risk of item duplication (such as during trading)
  • Optimalized for limited datastore budget

I am curious of how other people would go about this, and I am looking for some ideas and discussion on the topic. If you know of any great resources, articles or similar on the topic, I’d appreciate being pointed in the right direction.


The timing of your post is spot on because today it was announced that some DataStore improvements are planned, one of which is the ability to execute multiple all-or-nothing actions with a single API call.

Image for reference

Adam Miller mentioned ‘trading systems’ as one of its use cases, so it should most likely be a very safe feature to rely on once it releases.

One ‘cheesy’ solution for this could be to introduce a cooldown to trading, or to make the process very slow by adding long animations / transitions. This would of course not be the best user experience, so I would only use it if you have no other options. Although, on the other hand it does hinder scammers from emptying a poor victim’s account in seconds.


Batch queries will undoubtedly help prevent issues in the case that one of the 2 queries fails, although there’s still the issue of item duplication in general. Lots of front page games have been subject to item duplication glitches caused by players leaving and instantly rejoining in a very short timespan causing a race condition between the :Set/:UpdateAsync call and the :GetAsync call.

Session locking would also be a very good idea on new projects that incorporate trading to make absolutely sure these edge cases don’t create any duplicates of your uniquely identifiable items. There is a module that loleris open sourced recently that takes care of session-locking (and all of the edge cases like crashing servers) with a pretty ingenious use of UpdateAsync (I made a video explaining it here).

The module also allows you to view peoples “profiles” (saves) without putting a lock on it. In addition to that, there’s a GlobalUpdates feature that allows you to modify a save even if it’s already cached somewhere (which could be used for adding/removing items remotely).

I will definitely be using a wrapper for this module in all of my future projects as all of the hard work has already been done for us it seems.

1 Like

That’s a cool approach. I didn’t even consider session locking in the first place. Good idea!

1 Like

While it’s a really good idea and I did toy around with it a very small amount a few months back, all of the credit for this goes to loleris as he has been using this approach in his game Mad Murderer 2 since 2017. His game is one of (if not THE first) to have globally unique serialized items similar to Limited U items inside of his game. I was a very frequent player of that game (getting to #30 on the all-time leaderboard at one point) and I never saw a single case of duplicates or data loss so I have full faith in his module.

1 Like