RE:NODE

Minecraft11 min read

MySQL for Minecraft plugins and networks

Which Minecraft plugins need MySQL, how to connect LuckPerms, CoreProtect and others, sizing connection pools, and sharing data safely across a network.

0 readers

Most Minecraft plugins do not need MySQL. They store data in YAML files, SQLite or H2 inside their own folder, and on a single server that is fine. You need a real database server - MySQL, MariaDB, or PostgreSQL where the plugin supports it - in two situations: when several servers must see the same data (permissions, bans, economy across a network), or when a plugin writes so much that a local file database becomes the bottleneck, which in practice means CoreProtect on a busy server. Everything else can stay where it is.

This post covers which plugins benefit, how to connect them with the right settings, how many connections they open, and what to share across a network and what to keep separate.

When a database is worth it, and when it is not#

A plugin's storage choice decides two things: who can read the data, and how fast it can be written.

Local storage - YAML, SQLite, H2 - lives on the server's own disk and can only be used by that server's process. It needs no setup, nothing to keep running, and is backed up with the rest of the server folder. Its limits are concurrency (SQLite and H2 serialise writes) and reach (a second server cannot see it).

A database server is a separate process reached over the network. Any number of Minecraft servers can connect to it at once, it handles concurrent writes properly, and it can be queried from outside the game - a website showing ban lists or player stats, for example. The cost is another thing that has to be running, another set of credentials, another thing to back up, and a few milliseconds of latency on every query.

SituationUse
One server, ordinary pluginsLocal storage. Do nothing
One server, CoreProtect with heavy loggingA database server for CoreProtect
Two or more servers sharing permissionsA database server for LuckPerms
Network-wide bansA database server for the ban plugin
A website reading plugin dataA database server
Shared economy across serversA database server, with care (see below)

The trap is moving everything to MySQL because a guide said it is "better". A plugin that stores twenty kilobytes of config-like data and reads it once at startup gains nothing, and now depends on a database being up before the server can start.

Plugins that support a database, and what they store#

These are the common ones. Each plugin's own wiki is the authority on the exact keys for your version; the shapes below are the current ones.

PluginLocal defaultDatabase optionsWhy you would move it
LuckPermsH2MySQL, MariaDB, PostgreSQL, MongoDBShared permissions across servers
CoreProtectSQLiteMySQLWrite volume on busy servers
LiteBansH2MySQL, MariaDB, PostgreSQLNetwork-wide bans, web viewer
Plan (Player Analytics)SQLiteMySQLCombining stats from several servers
DynmapFilesSQLite, MySQLMap tiles in a database instead of files
BlueMapFilesSQL databasesThe same, for BlueMap
mcMMOFlat fileMySQLShared skills across servers

Some economy plugins can use a database too; EssentialsX does not, and stores balances in its per-player YAML files - the economy guide covers the database-backed alternatives.

Map plugins are a special case. Storing tiles in a database is possible but rarely a win: it moves a large, mostly static set of images into a database that then has to be backed up and served. Keep map tiles on disk unless you have a specific reason - Dynmap and BlueMap explains the trade.

Creating the database and the user#

Whatever engine you use, the pattern is the same: one database (or one table prefix) per plugin purpose, one user with rights on only that database, a strong generated password.

On a database server you manage yourself, in MySQL or MariaDB:

sql
CREATE DATABASE mc_luckperms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;CREATE USER 'mc_luckperms'@'%' IDENTIFIED BY 'a-long-generated-password';GRANT ALL PRIVILEGES ON mc_luckperms.* TO 'mc_luckperms'@'%';FLUSH PRIVILEGES;

utf8mb4 matters. Players put emoji and non-Latin characters in names of homes, shops, nicknames and chat; the older utf8 charset in MySQL stores only three bytes per character and fails on anything outside the basic plane. Most modern plugins create their tables in utf8mb4 when the database default allows it.

'%' allows connections from any address. If the database and the Minecraft servers are on a private network, restrict it to that range instead. If the database is reachable from the internet, a strong password is the only thing standing between it and every scanner on the planet - see the database security checklist.

On a panel host you usually do not run these statements yourself. On RE:NODE, every Minecraft plan includes a database slot: you create it from the panel and it comes with a generated host, user and password, plus an "Open in phpMyAdmin" button that signs you in with a one-use token for browsing tables and running queries. Those three values are what you paste into the plugin config.

Connecting LuckPerms#

LuckPerms is the plugin most people move first, and its config is a good template for the rest. In plugins/LuckPerms/config.yml:

plugins/LuckPerms/config.yml
storage-method: mysqldata:  address: db.example.com:3306  database: mc_luckperms  username: mc_luckperms  password: 'a-long-generated-password'  pool-settings:    maximum-pool-size: 10    minimum-idle: 10    maximum-lifetime: 1800000    keepalive-time: 0    connection-timeout: 5000  table-prefix: 'luckperms_'messaging-service: auto

The lines that matter:

  • storage-method takes mysql, mariadb, postgresql or mongodb for remote storage. Use mariadb if the server is MariaDB; the drivers differ slightly.
  • address includes the port. Leave it off and the default port for the engine is assumed.
  • messaging-service: auto makes LuckPerms push changes between servers. With SQL storage and no Redis, it falls back to polling the database. This is what makes /lp user Steve parent add vip on one server take effect on the others without a restart.

To move existing permissions rather than start over, run /lp export backup on the old storage, switch the config, restart, then /lp import backup. The export lands in the LuckPerms folder as a compressed file; keep it as a backup either way. The LuckPerms guide covers groups and contexts once the storage is settled.

Connecting CoreProtect#

CoreProtect logs every block change, container transaction and chat line. On a busy survival server that is millions of rows a week, and SQLite starts to struggle - lookups take seconds, and the consumer queue that writes logs can fall behind. That is when MySQL earns its keep.

plugins/CoreProtect/config.yml
use-mysql: truetable-prefix: co_mysql-host: db.example.commysql-port: 3306mysql-database: mc_coreprotectmysql-username: mc_coreprotectmysql-password: 'a-long-generated-password'

CoreProtect does not migrate SQLite data into MySQL on its own. Switching starts a new, empty log; the old database.db stays in the plugin folder. Either accept a fresh start (and keep the old file around for a few weeks for lookups by switching back temporarily), or use a migration tool you trust and test it on a copy first.

Plan the size. CoreProtect is the plugin most likely to fill a database. Set purge habits from the start - /co purge t:30d removes data older than thirty days - and schedule it, because a three-year-old block log is rarely worth the disk. Do not share CoreProtect tables between servers: each server's coordinates and world names would mix. Give each server its own database or its own table-prefix.

Connection pools: how many connections you actually open#

Almost every Java plugin that talks to a database uses a connection pool, usually HikariCP. A pool opens a fixed number of connections at startup and keeps them open so queries do not pay the cost of connecting. That is efficient for the plugin and easy to underestimate for the database.

The arithmetic is plugins multiplied by servers multiplied by pool size:

SetupCalculationConnections
One server, LuckPerms default pool1 x 1010
One server, LuckPerms + CoreProtect + LiteBans10 + a few + 1025 or so
Four-server network, same three plugins4 x 25about 100
Same network plus a proxy LuckPerms100 + 10about 110

MySQL's default max_connections is 151, and managed or shared database plans often allow fewer. A small network can run out without anyone noticing until a restart, when every server tries to open its pool at once and the last one gets Too many connections.

For Minecraft workloads, small pools are fine. A LuckPerms pool of 3-5 per server is plenty for a network under a few hundred players; it mostly caches in memory and queries the database on login and on change. Lower maximum-pool-size and minimum-idle together. Connection pools and limits explains why a bigger pool is often slower, not faster.

Sharing data across a network#

The reason most people end up here is a proxy network: a lobby, a survival server and a minigames server behind Velocity. What to share and what not to:

permissionsVelocityLuckPermsLobbyLuckPerms, LiteBansSurvivalLuckPerms, CoreProtectMinigamesLuckPerms, statsDatabase serverone schema per purpose
One database server behind a small network

Share permissions (LuckPerms, same database and prefix everywhere, including the proxy), bans and mutes (the ban plugin's network mode), and anything you want a website to show.

Do not share block logs (CoreProtect, per server), world-specific data such as claims or regions (they reference coordinates in one world), and plugin data where the plugin's documentation does not explicitly support multiple servers writing at once. Two servers writing to tables a plugin assumes it owns produces silent corruption, not errors.

Share with caution: economy balances and inventories. A shared balance means a purchase on one server and a payment on another can race; a plugin built for networks handles that with locking, a plugin that merely supports MySQL may not. Inventory sync plugins can duplicate items when a server crashes mid-transfer. Many networks deliberately keep a separate economy per gamemode for exactly this reason.

Database and servers should be close. Every query pays the round trip, and plugins that query on the main thread (badly written ones do) stall the tick for that long. A database on the same machine or network costs well under a millisecond; one on another continent costs 100 ms per query, which is two full ticks.

Running PostgreSQL or MongoDB instead#

MySQL and MariaDB are the lowest common denominator - nearly every plugin with database support speaks them. PostgreSQL and MongoDB are supported by fewer plugins, but the ones that matter most for networks often do: LuckPerms supports both, LiteBans supports PostgreSQL. If you are running a dedicated database for a network anyway, check each plugin you need before choosing an engine.

Database hosting on RE:NODE offers PostgreSQL and MongoDB as separate servers with a generated superuser password, reached on the plan's own host and port - a reasonable home for LuckPerms and a ban plugin across a network, provided every plugin you need supports the engine. The game plan's own database slot is the simpler choice for plugins that only speak MySQL. Postgres or MongoDB goes through the difference if you have not used either.

Backups and maintenance#

A plugin database is now part of your world. Restoring the world folder from Tuesday while permissions and bans stay on Friday is a mismatch you will notice. Back up both on the same schedule, and before any plugin update that mentions a "database migration" in its changelog.

bash
$ mysqldump --single-transaction --default-character-set=utf8mb4 \    -h db.example.com -u mc_luckperms -p mc_luckperms > luckperms.sql

--single-transaction takes a consistent snapshot of InnoDB tables without locking them, so the servers keep running during the dump. For CoreProtect, the dump can be large; purge old data first and the dump shrinks with it. Database backups and restores covers schedules and testing.

Two maintenance habits worth having: purge old log rows on a schedule rather than waiting for the disk to complain, and check the database's slow query log occasionally - a plugin issuing a query without an index shows up there long before players notice lag.

Troubleshooting connection errors#

`Communications link failure`. The plugin could not reach the database at all. Wrong host or port, the database is down, or a firewall is in the way. Test with any MySQL client from the same machine before blaming the plugin.

`Access denied for user 'x'@'y'`. Wrong password, or the user exists but is not allowed from that host. The 'y' in the message is the address the database saw - compare it to the host part of the user you created.

`Unknown database`. The database name in the config does not exist, or has different capitalisation. On Linux, MySQL database names are case-sensitive.

`Too many connections`. The pool arithmetic above. Shrink pools, or find the plugin that leaks connections by watching the process list while the server runs.

`Public Key Retrieval is not allowed`. A newer MySQL server with caching_sha2_password authentication and a driver that refuses to fetch the key over an unencrypted connection. Either connect over TLS, or (on a private network) add allowPublicKeyRetrieval=true to the plugin's connection properties if it lets you set them.

Server freezes for a second at random. A plugin running queries on the main thread against a slow or distant database. spark will show the plugin and the JDBC call in the profile.

FAQ#

Is MySQL faster than SQLite for Minecraft plugins?

For a single server with light use, usually not - SQLite on fast local storage has no network round trip. MySQL wins under heavy concurrent writes, like CoreProtect on a busy server, and is the only option when several servers share data.

Can every server on my network use the same database?

They can use the same database server. Whether they share tables depends on the plugin: LuckPerms and ban plugins are designed for it, block loggers and claim plugins are not. When in doubt, give each server its own table prefix.

What happens if the database goes down?

Plugins that need it fail: LuckPerms may refuse logins or fall back to cached data, CoreProtect queues writes and then errors. Your worlds are unaffected. Start the database first and the game servers after, and avoid putting the database somewhere less reliable than the servers that depend on it.

Should I use MariaDB or MySQL?

For Minecraft plugins they are interchangeable. Where a plugin offers a separate mariadb option, use it with MariaDB, because it selects the matching driver.

How big will the database get?

LuckPerms and ban plugins stay small, typically a few megabytes even on large networks. CoreProtect is the exception and can reach gigabytes in months on a busy server. Purge old logs on a schedule and the size stays predictable.


Comments

Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.

0/2000