How to Switch from SQLite to MySQL on Your Minecraft Server
Migrate your Minecraft server from SQLite to MySQL or MariaDB. Step-by-step for LuckPerms, CoreProtect, LiteBans, EssentialsX, with connection pooling and troubleshooting.
Why Switch from SQLite to MySQL?
SQLite is the default storage backend for most Minecraft plugins because it requires zero configuration, the plugin creates a .db file in its folder and works immediately. For a single server with a handful of players, SQLite is perfectly fine. But it has real limitations that surface as your server grows:
- Concurrency, SQLite uses file-level locking. When multiple plugins or async tasks try to write simultaneously, they queue up. On a busy server this can cause brief freezes when several plugins commit data at the same time.
- Multi-server support, SQLite databases are local files. If you run a BungeeCord or Velocity network with multiple backend servers, each server has its own separate database. Player data does not sync across servers. MySQL, being a networked service, lets all servers share a single database.
- Performance at scale, SQLite performance degrades with large datasets. CoreProtect on a server with millions of block changes, or LiteBans with years of punishment history, will query noticeably slower on SQLite than on MySQL with proper indexing.
- Backup and tooling, MySQL has mature backup tools (mysqldump, replication, automated snapshots), monitoring dashboards, and query optimization tools. SQLite is backed up by copying a file, which risks corruption if done while the server is writing to it.
Installing MySQL or MariaDB
Most Minecraft hosting providers include MySQL access in their plans, check your panel for a database section. If you self-host, install MariaDB (the community fork of MySQL, fully compatible and generally preferred for performance):
# Debian / Ubuntu
sudo apt update && sudo apt install mariadb-server
# Start and enable the service
sudo systemctl start mariadb
sudo systemctl enable mariadb
# Run the security setup
sudo mysql_secure_installation
On CentOS/RHEL, use dnf install mariadb-server instead. The secure installation wizard prompts you to set a root password, remove anonymous users, and disable remote root login, say yes to all of these.
Creating a Database and User
Log into MySQL as root and create a dedicated database and user for your Minecraft server:
mysql -u root -p
CREATE DATABASE minecraft;
CREATE USER 'mcuser'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT ALL PRIVILEGES ON minecraft.* TO 'mcuser'@'localhost';
FLUSH PRIVILEGES;
If your Minecraft server runs on a different machine than the database, replace 'localhost' with the Minecraft server's IP address or '%' for any host (less secure). For managed hosting, your panel will provide the database host, port, name, user, and password, you will not run these commands manually.
Configuring Plugins for MySQL
Each plugin has its own database configuration section. Here are the most commonly migrated plugins:
LuckPerms
Open plugins/LuckPerms/config.yml:
storage-method: MySQL
data:
address: localhost:3306
database: minecraft
username: mcuser
password: strong_password_here
pool-settings:
maximum-pool-size: 10
LuckPerms has built-in HikariCP connection pooling, so the pool-settings section is already optimized by default. Restart the server after saving.
CoreProtect
Open plugins/CoreProtect/config.yml:
use-mysql: true
table-prefix: co_
mysql-host: localhost
mysql-port: 3306
mysql-database: minecraft
mysql-username: mcuser
mysql-password: strong_password_here
CoreProtect creates its tables automatically on first MySQL startup. The table-prefix prevents name collisions if multiple plugins share the same database.
LiteBans
Open plugins/LiteBans/config.yml:
sql:
driver: MySQL
address: localhost:3306
database: minecraft
username: mcuser
password: strong_password_here
prefix: litebans_
EssentialsX
EssentialsX stores player data in flat YAML files by default, not SQLite. However, EssentialsX supports MySQL for its economy (via Vault) and user data through the EssentialsX economy bridge. Check the EssentialsX wiki for the latest MySQL configuration format, as it has changed between versions.
Migrating Existing Data
Switching the storage backend does not automatically transfer your existing data. Each plugin handles migration differently:
LuckPerms Migration
LuckPerms has a built-in export/import system that makes migration painless:
# While still on SQLite:
/lp export luckperms-backup.json
# Switch config to MySQL and restart
# After restart (now on MySQL):
/lp import luckperms-backup.json
This transfers all users, groups, permissions, meta, and tracks. The export file is human-readable JSON, so you can inspect it before importing.
CoreProtect Migration
CoreProtect has a built-in migration tool. After switching the config to MySQL, CoreProtect will detect the existing SQLite database and offer to migrate it. This can take a long time on large databases, a server with 50 million logged actions might take 30-60 minutes to migrate. Run the migration during off-hours and keep an eye on the console for progress messages.
LiteBans Migration
LiteBans supports /litebans import which reads from the old SQLite database and writes to the new MySQL database. Run this after switching the config.
Connection Pooling, HikariCP
Most modern Minecraft plugins use HikariCP for database connection pooling. A connection pool keeps a set of database connections open and reuses them instead of opening a new connection for every query. This dramatically reduces latency and overhead.
You typically do not need to configure HikariCP manually, plugins bundle it with sensible defaults. But if you see connection timeout errors, check these settings:
- maximum-pool-size, The maximum number of connections in the pool. Default is usually 10, which is fine for a single server. On a network with 5 backend servers sharing one MySQL instance, you might lower each server's pool to 5 to avoid hitting MySQL's max connection limit.
- connection-timeout, How long to wait for a connection before throwing an error. Default 30 seconds is reasonable.
- max-lifetime, How long a connection stays in the pool before being refreshed. Should be set lower than MySQL's
wait_timeout(default 8 hours).
Common Issues
Connection refused, MySQL is not running, or the host/port is wrong. Verify with mysql -u mcuser -p -h localhost from the server's command line. If the database is on a different machine, check firewall rules for port 3306.
Authentication plugin error, MySQL 8+ defaults to caching_sha2_password authentication, which some older JDBC drivers do not support. Fix by changing the user's auth method: ALTER USER 'mcuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';, or better, use MariaDB which uses the compatible plugin by default.
Too many connections, MySQL's default max_connections is 151. If you run many plugins and servers all pooling connections, you can hit this. Increase it in /etc/mysql/my.cnf: max_connections = 300.
For more on server optimization, see our full optimization guide and Paper vs Spigot comparison.
Need better performance? Astroworld Hosting runs NVMe SSD, up to 96 GB RAM, and DDoS protection on every plan. See features , plans from €6.39/mo.