Skip to main content

Storage and backups

Use local storage to get started. Use shared SQL or MongoDB storage when recordings need to be available on several machines.
Not sure which one to pick? Stay with the default (spatial, local files) until you actually run more than one server. You can switch later — see Deletion and migration.

Choose a backend

Set the case-sensitive id in storage.backend. The built-in ids are spatial, sql and mongodb; an unknown id fails startup with the list of known ids. Startup resolves a fixed set of factories shipped with Reverse. It does not discover backend plugins or scan Bukkit services for storage factories. Your storage choice applies when the server starts and is used for both recordings and captured terrain. The folder itself is set by storage.recordings-folder: empty uses plugins/recordings, a relative path resolves against the plugin data folder’s parent, and an absolute path is used as-is. For the standard plugins/reverse-recorder data folder: Configure the same resolved folder for recorder and standalone player on one machine. Folder changes require a restart and do not automatically copy, migrate, or import the old dataset.
Redis is not replay storage. It can coordinate lobby transfers, but events, metadata, and captured terrain still need local, SQL or MongoDB storage.

Sharing local storage between roles

Recorder and player can use the same spatial archive on one machine, even though they run as independent plugins. A player that was started before a new recording can discover its saved terrain without restarting. Spatial writes use the permanent .spatial.lock file to coordinate access across plugin instances and processes. Each successful chunk write publishes its pack data and CAS index before completing. Readers refresh the index before reporting a chunk missing, and closing an idle reader cannot replace a newer index with its old copy. Keep .spatial.lock and .replay.lock in place while Reverse is running. They are managed coordination files, not stale recording data. Spatial storage requires filesystem locking and atomic file moves; use shared SQL or MongoDB for servers on different machines. When opening an archive whose CAS index is missing or behind its pack files, Reverse can rebuild the index from verified complete payloads. Corrupt or truncated packs fail explicitly; preserve the complete archive and logs for diagnosis rather than deleting individual files.

SQL configuration

Set storage.backend: sql and configure the nested database section. Port defaults in the generated file are MySQL-oriented, so use 5432 explicitly for PostgreSQL. The configured account needs permission to create Reverse’s tables and read/write its data. Back up before changing storage or updating the plugin, and avoid editing recording data directly in database tables. SQLite resolves storage.database.sqlite-file against the selected recordings folder, not the role’s own configuration folder. The defaults therefore select plugins/recordings/replay.db; changing recordings-folder also changes the base for a relative SQLite filename. An absolute SQLite path is used as-is. SQLite uses a single-connection pool. For a remote database, connection limits are configured under storage.database.pool. The database backend downloads the common SQL libraries and only the selected dialect’s driver group. MySQL and MariaDB use the MariaDB driver; PostgreSQL and SQLite have their own drivers. You do not need to install a separate JDBC plugin. A successful SQL startup does not create a spatial terrain provider alongside SQL.

MongoDB configuration

Use the same URI and database on recorder, player and lobby:
MongoDB 6.0 or newer is required. Replace the URI with your MongoDB endpoint and credentials when needed. The account must be able to create collections and indexes and read/write the database, including GridFS buckets. The driver is downloaded by Libby only when MongoDB is selected; no separate MongoDB plugin is needed. Replay bodies use replay_payloads GridFS and terrain uses replay_terrain GridFS, so replay bodies and world indexes can exceed MongoDB’s 16-MB document limit. Catalog queries read only metadata. Renaming and descriptions do not download or rewrite the recorded events. For cross-server playback, network.backend: mongodb uses the selected MongoDB backend’s availability collections. Redis remains an optional alternative. A replica set is not required for the storage publication scheme.

Fallback behavior

fallback-to-spatial: true allows a startup failure while loading/configuring the SQL or MongoDB backend to select local storage instead. This includes more than an unreachable endpoint. Fallback switches both replays and terrain and uses the same resolved recordings folder. SQL logs:
MongoDB logs Storage backend 'mongodb' unavailable; using 'spatial'. This is not replication, automatic re-upload, or a live switch back to the remote database. Repair the database and restart deliberately. Recordings created locally during fallback remain local unless you perform a separately planned transfer. For shared deployments, false is usually easier to operate: a node fails clearly instead of serving a different private catalog.

Catalog versus full replay loading

Browsing the catalog does not load every recording for playback. Renaming a replay or editing its description changes its catalog text, not the recorded scene. Reopen the catalog to see updated details.

Cache sizing

The shared configuration exposes maximum chunks, terrain indices (historically named manifests), and loaded replays. They are count limits, not megabytes. A loaded replay can be much larger than its compressed .rpl file. Leave cache limits at their defaults unless you have a reason to tune them. Watch server memory use when increasing them. Cache limits do not delete saved recordings.

Back up correctly

Back up events and terrain together. Copying only .rpl files can leave a recording without the world it needs to display.

Local storage

  1. Stop new recordings.
  2. Wait for pending saves, then stop the affected servers cleanly.
  3. Copy the entire configured recordings tree (plugins/recordings by default), including replay files, indices, and packs.
  4. Back up any SWM templates and their configured loader data separately.
  5. Restore a test copy and replay a known recording before relying on the backup.

SQL storage

Use the database engine’s consistent backup method for the entire Reverse dataset. Include all replay metadata/event tables and terrain data/index tables from the same consistent snapshot. Back up external SWM templates separately.

Redis

Availability data is short-lived coordination state, not the replay archive. A Redis snapshot alone cannot restore recordings. Stale heartbeats and expired pending selections are normal control-plane concerns, not lost replay payloads.

MongoDB storage

Back up the full Reverse database consistently, including replay_sessions, replay_cas_chunks, replay_world_indexes and both GridFS buckets’ .files and .chunks collections. Stop writers for a standalone backup or use MongoDB’s consistent-backup procedures. Back up external SWM templates separately. Deleting a replay removes its authoritative catalog document. Old replay generations and terrain blobs remain stored so a load already in progress on another server can finish safely. Storage usage is therefore not reclaimed immediately. Perform any orphan cleanup offline with all Reverse readers/writers stopped; there is no automatic online garbage-collection task.

Deletion and migration

Use the catalog’s authorized delete operation or a configured menu delete action for replay deletion. Do not assume deletion compacts terrain packs or provides a configurable retention schedule. No owner-facing automatic retention/garbage-collection command is documented by the current command surface. Changing between spatial, sql and mongodb does not import existing recordings. There is currently no general-purpose migration command. Keep the original backup and plan migration using supported storage APIs/tools for the exact build. The same applies when changing recordings-folder or the SQLite filename: the next startup opens the newly selected location, without moving data from the previous one.