Consider a game where the player has some profile or save data stored in a database. What I want to understand is, for things that effect the users score or level, there could be so many factors that this has to be persisted to the database and if it is, this could be many writes per second per player potentially, which could be expensive or slow.

How can I reduce the load on the database while still maintaining critical player information?

  • \$\begingroup\$ Questions about "what other games do" aren't considered on-topic here. Some games do use databases, though, and for those games it can be a performance issue to save to them constantly, so there are techniques that are pertinent to that scenario. I think that seems to be what you're actually after, here? \$\endgroup\$ – user1430 Apr 20 '16 at 18:14
  • \$\begingroup\$ @JoshPetrie Yes that's correct. I'm just trying to figure if there is a hybrid approach, but having things out of sych is not an option. \$\endgroup\$ – cool breeze Apr 20 '16 at 18:16

In the context of a game like an MMO (a class of game that often uses databases as the persistent storage), this problem is fairly common. Player data is very important, and you will certainly have it in-memory while the player is actively playing because it's way faster to access there.

However, you really don't want a server crash to cause player data loss, so you want to serialize the players state as often as possible. However, you also don't want to overload your database with too many writes.

There are lots of solutions to this problem. One that I'm familiar with, having worked on some MMOs, is to define two types of player save events: low priority and high priority. What each makes a save low or high priority depends on your game, but generally things that are economically impacting (anything involving real money transactions, or things involving the player gaining important items, et cetera) would be high priority. Things like current world position would be lower priority.

High priority saves get queued immediately when the relevant event happens. Low priority ones happen in the background at fixed(ish) intervals.

Note the term "queued:" Rather than a save immediately going to hit the database, the saveable data is bundled up, serialized into a save request and sent off to dedicated type of server that eventually saves the data to the main character record. These servers themselves may still store the pending saved state in a database (just in case they crash), but it's usually easier to deploy more of them to handle scaling, and they're usually way simpler and less prone to churn and bugs.

The main downside here (other than having to, you know, write all this infrastructure) is that the system is only eventually consistent. Without some careful though going in to how the save queue servers manage and prioritize the queues of pending saves, a crash of a game server can still result in apparent data loss for the player.

You can attempt to alleviate this by implementing a system wherein the login servers direct the queue server grid to flush the pending saves for a user that's about to log in, ensuring the most up-to-date data. If the queue management can easily prioritize and discard "old" pending saves, this can really help with the eventual consistency problems while still being fairly good at keeping load off the main character record database.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.