JoinGG

Databases for Game Servers: When You Need One and What Breaks

SQLite until it is not enough, MySQL after that. What plugins actually store, and the three failures that lose player data.

SweetMask · 7 min read

Most server owners meet databases by accident. A plugin's configuration file has a section about MySQL, they leave it on the default, and it quietly uses a file instead. Six months later there are forty thousand rows in it, the server pauses for a second every time someone opens their inventory, and nobody knows why.

Databases on a game server are not complicated, but the two decisions that matter are made early and are annoying to reverse. Here is what plugins store, when a file stops being enough, and the three failures that lose player data.

What is actually being stored

More than people expect, and almost all of it is player state.

Permissions and ranks. Who is staff, who bought what, who is in which group.

Economy. Balances, transactions, shop stock, market listings.

Homes, warps, claims. Coordinates and ownership.

Bans and punishments. Frequently shared across several servers, which is one of the main reasons to use a real database at all, SourceBans exists precisely to give a network one ban list.

Statistics. Playtime, kills, deaths, progression, leaderboards.

Logs. Some plugins write chat and block changes to a database rather than a file, which makes them searchable.

The world itself is usually not in a database: that is the game's own save format. What is in the database is everything the plugins added, and losing it means losing everything that made your server yours while leaving the terrain intact. That distinction matters for backups, because backing up the world folder and not the database is a very common half-measure.

SQLite, and when it stops being enough

Most plugins default to SQLite, which is a database that lives in a single file with no server process. It is good and it is the right answer for a long time.

It works well when: one server, a few dozen players, and reads vastly outnumber writes.

It starts hurting when:

  • Two servers need the same data. SQLite is a file, and two processes writing one file over a network share is how corruption happens. If you run a survival server and a creative server that share ranks, you need a real database.
  • Writes are frequent and concurrent. SQLite locks the whole file for a write. On a busy server with several plugins writing constantly, requests queue, and the symptom is a brief freeze rather than an error.
  • The file has grown large. Statistics and logging plugins accumulate rows indefinitely, and a database nobody prunes gets slower forever.

The tell: the server stutters at moments that correlate with player actions, someone opening a shop, a rank changing, a chunk of logging being written. If your tick rate drops in short spikes rather than sagging steadily, database writes are a good suspect.

MySQL and MariaDB

The standard answer once SQLite is not enough. MariaDB is a drop-in replacement for MySQL and either is fine.

What you gain: several servers can share one dataset, concurrent writes are handled properly, and the database can live on its own machine.

What it costs: another service to run, secure, back up and keep patched. That is a real ongoing cost and it is why moving before you need to is a mistake.

Do not expose it to the internet. A database listening on a public interface is one of the most-scanned things there is. Bind it to localhost if the game server is on the same machine, or to a private network if not, and firewall the port regardless. Security basics covers the firewall side.

Give each plugin its own user with access to its own database. Not one root account shared by everything. When a plugin is compromised or simply badly written, the damage is bounded.

Migrating without losing anything

Plugins that support both usually have a conversion command. Where they do not, the procedure is the same:

  1. Stop the server. Copying a database that is being written to produces a file that is subtly wrong.
  2. Back up the SQLite file, and confirm it exists and is a plausible size.
  3. Create the MySQL database and user.
  4. Run the plugin's conversion, or export and import manually.
  5. Start the server and verify with real data — check a specific player's balance, rank and homes against what they had. Not "does it start", does it have the right numbers.
  6. Keep the old file for a month.

The step people skip is five, and the failure it catches is a conversion that succeeded technically and dropped a table.

The three failures that lose data

  1. The backup that only covers the world. Extremely common. The world folder is backed up nightly, the database is not, and a restore produces the terrain with none of the balances, ranks or claims. If your plugins use a database, it is part of the backup or the backup is incomplete. Game server backups covers doing it properly.
  1. Copying a database while the server is running. Produces a file that opens fine and is missing recent writes, or is corrupt in a way that appears weeks later. Stop the server, or use the database's own dump tool; mysqldump for MySQL, .backup for SQLite, which handles consistency for you.
  1. A disk that fills up. A database that cannot write does not always announce itself loudly. Some plugins fail silently and drop the write. df -h is free and worth watching, and logs and old backups are the usual culprits for filling a disk. Reading game server logs covers rotation.

Maintenance that takes ten minutes a quarter

Prune what accumulates. Statistics, logs and transaction history grow forever unless something removes old rows. Most plugins have a retention setting nobody has ever changed. A database that has grown to several gigabytes on a thirty-player server is almost always one unbounded table.

Check the size. If it is much larger than you expect, find out which table.

Confirm the backup is running and restore one. An untested backup is a hypothesis, and databases are where that hypothesis most often turns out to be false.

Update it. MySQL and MariaDB receive security patches like anything else.

Sharing one database across several servers

The main reason to move off SQLite, and worth doing deliberately rather than by accident.

What benefits from sharing: bans, ranks and permissions, economy balances, playtime and statistics. A player banned on one server should be banned on all of them; a rank bought once should apply everywhere. This is what turns several servers into a network rather than several unrelated servers.

What should not be shared: anything tied to a specific world. Homes, claims, warps and locations mean nothing on a different map, and sharing them produces players teleporting into terrain that does not exist.

Use separate databases, not separate tables in one. Give each plugin its own database and its own user. It costs nothing, keeps backups granular, and means a misbehaving plugin cannot touch another's data.

Watch the latency. A database on a different machine adds a network round trip to every query. Over a fast local network this is irrelevant; across the internet between two providers it is not, and a plugin that queries per player action will make the server stutter. Keep the database close to the servers that use it.

Back it up once, centrally. One of the underrated benefits: instead of several SQLite files scattered across machines, there is one thing to back up and one thing to test restoring. Game server backups covers the discipline.

Before doing any of this, it is worth asking whether you should be running several servers at all: when to run a second server covers why splitting a population is usually the wrong move, and the shared database is the part that makes it survivable when it is the right one.

When you do not need one

Most servers do not.

A round-based server — deathrun, prop hunt, surf, a deathmatch server, stores almost nothing that persists. Ranks and records at most, and SQLite handles that indefinitely.

The servers that need a real database are the ones with persistent player state and a lot of it: survival and economy servers, DarkRP, roleplay, anything with progression, and anything running more than one server that shares data.

If you are not sure which you are, you are almost certainly the first kind, and adding MySQL to a server that does not need it is adding a component that can fail for no gain at all.

Signs the database is your problem

Useful because database issues rarely announce themselves as database issues.

Short stutters correlated with player actions. Someone opens a shop, someone's rank changes, someone teleports, and the server hitches for a fraction of a second. Steady low performance is usually something else; brief spikes tied to actions are usually a write.

The hitch gets worse over months, not hours. A leak degrades over a session; a database degrades as the table grows. If a restart does not help, that points away from memory and towards storage.

Plugin errors mentioning locks or timeouts. database is locked on SQLite, or connection timeouts on MySQL, are unambiguous. Reading game server logs covers finding them.

Data that silently does not save. A player's balance reverting, a home that disappears, a rank that has to be set twice. Frequently a failed write nobody noticed, and frequently a full disk underneath it.

A database file that is surprisingly large. Several gigabytes on a small server is nearly always one unbounded logging or statistics table.

Checking any of these takes a few minutes and rules out a category of problem that otherwise gets misattributed to hardware.

To sum up

Start with the default, which is usually SQLite. Move to MySQL when you have two servers sharing data or a measurable stutter under write load, not before. Back up the database alongside the world, never separately. Prune the tables that grow forever. And test a restore once, deliberately, before you need one, that single hour is worth more than everything else on this page.

Common questions

Can I share player homes and land claims across my server network?
No, you should not share data tied to a specific world across servers. Homes, claims, warps, and coordinates mean nothing on a different map, and sharing them causes players to teleport into terrain that does not exist.
How can I safely back up a database without shutting down my game server?
Use the database's dedicated dump tool instead of directly copying the file. Run mysqldump for MySQL databases or the .backup command for SQLite, which safely handles data consistency while the server is active.
Why is my server lagging whenever a player makes a purchase or changes rank?
Your database is likely struggling with write operations. SQLite locks its entire file during a write, causing requests to queue and creating brief freezes during player-triggered actions like shop transactions or rank updates.
Tags
server admindedicated serversdatabasemaintenancemods
Share

SweetMask

Published · 7 min read

All articles

Keep reading