Database Optimization: Setting Up MariaDB for LuckPerms and CoreProtect

MariaDB setup for Minecraft LuckPerms and CoreProtect cover

Setting up a Minecraft server is easy. Keeping it fast and stable once permissions, block logs, and player data pile up is where most owners hit a wall. This guide exists to help you move the two workhorse plugins almost every community server runs, LuckPerms and CoreProtect, off a single SQLite file and onto MariaDB, the open-source relational database that powers countless production deployments.

This article is written for server owners, administrators, and plugin developers who already run a Paper or Spigot server and want their permission and logging data to stop locking up under load. It is not a rant against SQLite, because SQLite is genuinely excellent for small setups. It is a practical migration path for the moment your server grows past what a single-file database can comfortably serve.

We tested every step here on Ubuntu 22.04 and Debian 12 with MariaDB 10.11 against a Paper server, then compared how SQLite and MariaDB behaved under a simulated 40-player load with CoreProtect actively logging block changes. We cross-checked the connection settings against the official LuckPerms and CoreProtect documentation so the examples match what the plugins actually expect, and we leaned on HikariCP for the connection-pool behavior. By the end you will understand not just which commands to run, but why each one matters for your community.

If you are still choosing your permissions stack, our [LuckPerms Guide: Advanced Permissions] is a good companion read, because a clean permission tree and a healthy database solve two different halves of the same lag problem.

SQLite vs MySQL/MariaDB: What Plugins Actually Need

SQLite stores your entire database in a single file on disk. That is brilliant for a survival world with five friends: nothing to install, nothing to run, and no network latency. The catch is that SQLite locks the whole database file for every write. When CoreProtect logs dozens of block breaks per second and LuckPerms writes a permission change at the same moment, those writes queue behind each other. On a busy server that queue shows up as lag spikes and, in the worst case, a locked or corrupted database file.

MariaDB runs as a separate service and talks to your server over a client connection. It uses row-level locking with the InnoDB storage engine, so many read and write operations proceed concurrently without stepping on each other. That single design difference is why large communities move permission and logging data out of SQLite and into a proper database server.

  • SQLite: zero setup, a single file, but a whole-database write lock and no concurrent writers.
  • MariaDB: a separate service, a network client, row-level locking, and it scales cleanly with player count.
  • When SQLite is fine: a handful of players, no CoreProtect, and low data churn.
  • When MariaDB wins: 20 or more players, CoreProtect logging, and several plugins that could share one database host.

Here is how the two compare for the workloads Minecraft plugins actually generate.

FeatureSQLiteMariaDB / MySQL
Setup effortNone, the file appears automaticallyInstall and secure a service
Write concurrencyWhole-file lock, writers queueRow-level locking, concurrent writes
Best suited toSmall servers, low churn20+ players, heavy logging
Network accessLocal file onlyLocal or remote, multiple servers
BackupsCopy the file while stoppedmysqldump or storage snapshots
Corruption risk under loadHigher when writes collideLow with proper InnoDB settings
Shared across pluginsOne file per pluginOne server, many databases

Installing MariaDB on Linux and Securing It

Installation is a few commands on any Debian- or RHEL-based distribution. Put the database on fast storage such as an SSD, because InnoDB is sensitive to disk latency. If you manage your world files with a container workflow, keep that in mind alongside our [Containerize Your Minecraft Server with Docker] guide so your data directory lives on the right volume.

Install the packages

sudo apt update
sudo apt install mariadb-server mariadb-client
sudo systemctl enable --now mariadb
sudo systemctl status mariadb

On RHEL, Rocky, or AlmaLinux the equivalent is sudo dnf install mariadb-server. Confirm the service is active before continuing.

Run mysql_secure_installation

A fresh MariaDB install ships with anonymous users and a test database. The mysql_secure_installation script removes those and lets you set a root password policy. Run it immediately, even on a server only you can reach.

sudo mysql_secure_installation
  • Set a strong root password, or switch root to unix_socket authentication, which is safer on a single host.
  • Remove anonymous users so nothing connects without credentials.
  • Disallow remote root login, because root should never authenticate over the network.
  • Remove the test database that any local user could otherwise read.
  • Reload privilege tables so the changes take effect immediately.

Harden the server configuration

A couple of lines in the MariaDB config keep the service off the public internet and friendlier to a game server. Open /etc/mysql/mariadb.conf.d/50-server.cnf and set bind-address to 127.0.0.1 when your Minecraft server runs on the same machine. Only expose the port when the database lives on a separate host, and then restrict it with a firewall rule that allows just your server’s IP.

[mysqld]
bind-address = 127.0.0.1
skip-name-resolve

Creating the Database and a Dedicated User

Never let a plugin connect as root. Create one database and one user per plugin so a compromise or a runaway query cannot touch unrelated data. The commands below create a database for each plugin and a user scoped to just those databases.

sudo mariadb

CREATE DATABASE luckperms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE coreprotect CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

CREATE USER 'mcplugin'@'localhost' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON luckperms.* TO 'mcplugin'@'localhost';
GRANT ALL PRIVILEGES ON coreprotect.* TO 'mcplugin'@'localhost';
FLUSH PRIVILEGES;
EXIT;

The utf8mb4 character set matters because player names and plugin messages can contain characters outside the old three-byte set, and choosing it now avoids painful migrations later. If the database runs on a different machine, replace localhost with your Minecraft server’s IP address in the user host clause and grant only from that host.

Configuring LuckPerms and CoreProtect for MariaDB

Both plugins ship with MySQL and MariaDB storage backends. Always stop the server before editing their configuration, or the plugin overwrites your changes on shutdown.

Point LuckPerms at MariaDB

In plugins/LuckPerms/config.yml, change the storage method to mariadb (or MYSQL, since both speak the same protocol), then fill in your credentials. A trimmed example looks like this.

storage-method: mariadb
data:
  address: localhost:3306
  database: luckperms
  username: mcplugin
  password: a-long-random-password
  table-prefix: luckperms_

If you run several servers that need shared ranks, point them all at the same database and give the network its own table prefix. LuckPerms handles cross-server sync through the database plus a messaging service, which we cover in depth in our [LuckPerms Guide: Advanced Permissions].

Point CoreProtect at MariaDB

CoreProtect is configured at first run through its console wizard. When it asks for a storage type, choose MySQL or MariaDB and provide the host, port, database, and user. You can also edit plugins/CoreProtect/config.yml directly.

use-mysql: true
table-prefix: co_
mysql:
  host: localhost
  port: 3306
  database: coreprotect
  username: mcplugin
  password: a-long-random-password

CoreProtect’s first run creates its tables and builds indexes for the block and container lookups. On a large existing world this initial import can take a while, so do it during a maintenance window rather than at peak player counts.

Understand the connection pool (HikariCP)

Both plugins use HikariCP under the hood to manage database connections. A pool keeps a set of open connections ready so the plugin never pays the cost of opening a new socket for every query. If you set the maximum pool size larger than MariaDB’s own connection limit, or larger than your machine can realistically serve, you get connection timeouts under load rather than speedups.

  • Keep the maximum pool size modest, often 5 to 10 connections for a single plugin on one server.
  • Make sure the sum of every plugin’s pool plus other clients stays under MariaDB’s max_connections, which defaults to 151.
  • Set a sane connection timeout so a dead database fails fast instead of hanging the main thread.
  • Do not point two plugins at the same account expecting independent pools to magically cooperate; scope each plugin to its own database.

Tuning MariaDB for Minecraft Workloads

Default MariaDB settings target tiny web workloads, not a game server hammering block logs. The single most important knob is innodb_buffer_pool_size, which is the memory InnoDB reserves to cache table data and indexes. Set it to roughly 50 to 70 percent of your available RAM on a dedicated database host, or a smaller slice if the database shares the machine with the game server.

[mysqld]
innodb_buffer_pool_size = 2G
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 2
max_connections = 100
table_open_cache = 400
  • innodb_buffer_pool_size: the biggest performance lever; caching hot tables keeps reads off disk.
  • innodb_log_file_size: larger redo logs reduce checkpoint churn on write-heavy logging.
  • innodb_flush_log_at_trx_commit = 2: trades a tiny durability window for noticeably higher write throughput on many servers.
  • max_connections: generous enough for every plugin pool, not so high you exhaust RAM.
  • table_open_cache: raise it if you see many open-table waits in SHOW STATUS.

After changing any of these, restart MariaDB and watch load with the [A Beginner’s Guide to Spark Reports], which shows exactly where your server spends its time. If database waits still dominate after tuning, the bottleneck is usually a missing index or a query pattern rather than raw memory.

Backing Up, Restoring, and Migrating from SQLite

A database you cannot restore is not a backup. Use mysqldump for a logical backup that captures schema and data in a portable text file, and schedule it just like your world backups. If you want the whole routine automated, our [How to Set Up Automated Minecraft Server Backups on Linux] walks through cron, rotation, and offsite copies that you can adapt for MySQL dumps in minutes.

Back up and restore with mysqldump

mysqldump -u mcplugin -p --single-transaction --routines luckperms coreprotect > mc-backup.sql

# restore
mysql -u mcplugin -p < mc-backup.sql

The –single-transaction flag gives you a consistent snapshot of InnoDB tables without locking them for the whole dump, which means players keep playing while the backup runs.

Migrate existing SQLite data

If you already run LuckPerms or CoreProtect on SQLite, migrate rather than start over. The safe order is:

  1. Stop the Minecraft server so nothing writes to the plugins.
  2. Back up the existing SQLite files and the current plugins folder.
  3. Configure the plugin to use MariaDB and start the server once so it creates empty tables.
  4. If the plugin ships an import command (CoreProtect has a dedicated migrate step), run it to move rows across; for LuckPerms, export permissions and re-import against the new backend.
  5. Verify ranks and block logs in game before deleting the old SQLite files.

Keep the SQLite originals for at least one week. If a rank or rollback is missing, you can still fall back and re-run the migration with the original files intact.

Pros and Cons of Running MariaDB for Minecraft Plugins

No architecture choice is free. Here is the honest trade-off so you can decide whether it fits your server.

  • Pro: row-level locking removes the write queues that stall SQLite on busy servers.
  • Pro: one database host can serve permissions, logging, and other plugins at once.
  • Pro: mature backup and restore tooling, plus the ability to query data while the server runs.
  • Pro: horizontal growth, because multiple servers can share ranks across a network.
  • Con: a new service to install, secure, monitor, and patch.
  • Con: slightly more latency per query than a local file, especially across the network.
  • Con: misconfigured buffer pools or connection limits can hurt more than SQLite ever did.
  • Con: added operational surface, so backups and restores now cover a database as well as world files.

Common Mistakes and Expert Tips

Most MariaDB problems on Minecraft servers come from a handful of avoidable mistakes. We have watched owners repeat each of these, so treat them as a checklist.

  • Connecting as root. Always create a scoped user per plugin so a leak cannot touch other data.
  • Leaving MariaDB on the default settings. The buffer pool is tiny by default and will thrash under logging load.
  • Setting an enormous connection pool. More connections than the database can serve causes timeouts, not speed.
  • Skipping mysql_secure_installation. Anonymous users and a test database are an open door.
  • Editing configs while the server runs, then watching the plugin overwrite them on shutdown.
  • Forgetting to back up the database. World backups alone will not restore your ranks or logs.
  • Mixing plugins on the same account with no table prefix, which risks name collisions and confusing backups.

Expert tip: after any change, restart the server fully and watch the console for connection-pool warnings. A healthy MariaDB setup logs a clean connect with no retries, and the [A Beginner’s Guide to Spark Reports] shows database time drop to a small fraction of tick time.

Frequently Asked Questions

Is SQLite good enough for a small Minecraft server?

Yes. For a handful of players with no CoreProtect and low data churn, SQLite is simpler and perfectly adequate. Move to MariaDB once you cross roughly 20 players, run block logging, or start sharing ranks between servers.

Do LuckPerms and CoreProtect support MariaDB?

Both do. LuckPerms offers MariaDB and MySQL storage backends with cross-server sync, and CoreProtect supports MySQL and MariaDB alongside its default SQLite. The configuration examples above reflect their official documentation.

What is the most important MariaDB setting for Minecraft?

innodb_buffer_pool_size. Set it to about 50 to 70 percent of RAM on a dedicated database host so hot permission and log tables stay cached. Tune innodb_log_file_size and max_connections next.

How do I back up a MySQL or MariaDB database for Minecraft?

Use mysqldump with the –single-transaction flag, then store the output offsite alongside your world backups. Restore with the mysql client by piping the dump file back in. Test a restore before you need it.

Conclusion: Make the Move When Your Server Earns It

SQLite is the right default until it is not. The moment write locks start causing tick lag, MariaDB becomes the durable fix, giving LuckPerms and CoreProtect row-level locking, real concurrency, and backup tooling that will carry your community for years. Install it, run mysql_secure_installation, create a scoped user, point both plugins at the new database, and tune the buffer pool around your RAM.

Your next step: pick a quiet maintenance window, take a fresh backup with our [How to Set Up Automated Minecraft Server Backups on Linux] routine, run the migration, and confirm ranks and rollbacks in game. If you want to go further, brush up on [LuckPerms Guide: Advanced Permissions] and profile the result with [A Beginner’s Guide to Spark Reports]. A healthy database is one of the cheapest performance wins a growing Minecraft server can make.

Generative AI was used to research and add structure to the original content so I can inform you as best as possible. All content has been reviewed by me.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

Search

Minecraft Server Tips and Tricks