A plugin that logs every block break, every login, every economy transaction is writing constantly. Point it at a .db file instead of a real database server, and every one of those writes can end up queuing behind the main thread — which is a very roundabout way to lose TPS to a feature nobody would call performance-critical.
The mechanism
SQLite is not a server — it is a library that reads and writes a single flat file directly, with no separate process managing access. To keep that file consistent, SQLite's default mode allows one writer at a time: while a write is happening, every other connection wanting to write has to wait for it to finish, and by default even readers can be held up.
A plugin logging block changes, chat, or economy transactions writes constantly, and each one of those writes has to acquire that file lock. If the plugin's database calls happen on the main thread rather than a background one, that wait becomes a wait the entire game is doing — every player, every entity, frozen for the length of a disk write.
SQLite versus a MySQL server
SQLite (.db file) | MySQL | |
|---|---|---|
| What it is | A library linked into the plugin, writing straight to a file | A separate server process, accessed over a connection |
| Concurrent writes | One at a time, file-locked | Many, with row-level locking in InnoDB |
| Where the wait happens | Whichever thread issued the write — often the main thread | The plugin's own connection, which a well-written plugin keeps off the main thread |
| Good fit for | A single-player tool, a low-traffic personal server | Any plugin logging more than the occasional event |
Plenty of plugins that behave perfectly on MySQL default to SQLite because it needs no setup — and the same plugin, same settings, same server, can go from unnoticeable to a visible TPS drop the moment write volume increases, with nothing in the plugin's own code having changed at all. The database engine is the variable, not the plugin's quality.
Moving a plugin off SQLite
- Check the plugin's config for a storage or database section
Almost every plugin capable of using MySQL exposes host, port, database name, username and password fields — usually commented out or set to SQLite by default.
- Point it at the MySQL database included with your plan
Create one from the Databases tab if you have not, and use the local host address shown there rather than a public IP.
- Restart once, and confirm in the plugin's own startup log
Most print a line confirming which engine they connected to. That line is the proof the switch took, not just that the config file changed.
The plugin's log confirms a MySQL connection, and TPS stays steady during the activity that used to cause a dip — mass block breaking, a busy shop, a login wave.