Progression storage
McProgression supports YAML, SQLite, MySQL, and PostgreSQL. SQLite is the default and needs no database server. JDBC drivers are supplied by Paper's plugin library loader; the plugin does not require CoreProtect or its database.
Choose a backend
Edit plugins/McProgression/config.yml and restart the server:
storage:
backend: sqlite # sqlite | mysql | postgresql | yaml
sqlite-file: progression.db
jdbc-url: ""
username: ""
password: ""
table-prefix: mcprogression_
For MySQL, configure backend: mysql and a URL such as jdbc:mysql://db-host:3306/mcprogression?sslMode=VERIFY_IDENTITY. For PostgreSQL use backend: postgresql and jdbc:postgresql://db-host:5432/mcprogression?sslmode=verify-full. Put driver-specific TLS, timeout, and connection options in the JDBC URL. Create the database and grant the plugin user table creation and read/write access. McProgression creates its own prefixed state table.
Keep passwords out of shared configuration. Set password: "${ENV:MC_PROGRESSION_DB_PASSWORD}" and provide that environment variable to the Minecraft server process. Environment placeholders are resolved for the password and JDBC URL. The server must be able to reach the database host and download the Paper libraries on first startup.
Existing YAML progress
When the selected SQL table is empty, startup imports progress.yml into that database in one transaction and keeps the YAML file unchanged as a backup. Once the table has data, SQL is authoritative. If SQL is configured but unreachable, plugin startup fails rather than silently loading an empty YAML profile. Switching backends is not an automatic live replication feature: stop the server and perform an explicit export/import after backing up both stores.
The YAML backend remains available with storage.backend: yaml, mainly for small servers, development, and migration. It rewrites the full state file on the server thread, so large profiles can cause save-time pauses. For a busy server, prefer SQLite for a single Paper process or a properly hosted MySQL/PostgreSQL instance if remote database administration is needed. A remote database adds network and operational dependencies; it is not automatically faster than local SQLite.
SQL snapshots are flattened from the in-memory state on the server thread, then written by a dedicated database thread. Saves are coalesced by the progression service, and the database writer keeps at most one pending full snapshot: if it is still processing an older snapshot when another save arrives, the newer complete snapshot replaces the not-yet-started one. This bounds queued snapshot memory while preserving the latest full state. The JDBC work itself remains off the server thread. Shutdown queues a final snapshot and waits up to 15 seconds for the writer to flush. Keep regular database backups; this is persistence, not a substitute for backups.
For servers expecting 100+ concurrent players, use SQL rather than YAML and monitor Paper tick times, database availability, and server storage. Keep the database close to the Minecraft host with reliable low-latency connectivity. Do not treat each XP action as a database transaction: XP changes are accumulated in memory and persisted periodically. A database outage can therefore delay durability until a later successful save; do not terminate the process abruptly during that interval.
MySQL and PostgreSQL currently support a single active Paper writer for a progression store. They do not enable safe cross-server shared progression or multi-writer operation. Use separate stores for separate servers unless and until coordinated multi-server writes are implemented.
One server per database
Each database is designed for one active Paper server writer. Do not point multiple concurrently running servers at the same progression database; shared writes and cross-server synchronization are not supported. Use separate databases for separate servers. SQL writes run asynchronously, but a database outage can delay saving recent progress, so keep regular backups and monitor database availability.