Skip to content

Storage Backends

Petrus Pradella edited this page Jul 23, 2026 · 8 revisions

Storage Backends

Where PlayerData, PDSections and account data physically live is an admin decision, made in plugins/EverNifeCore/storage.yml. Plugins advise a default; the admin has the final say. The storage engine is EveryDatabase - EverNifeCore configures and drives it.

The file is generated with a full set of commented, disabled example backends on first boot, so most admins only flip enabled and fill in credentials.


The shape of storage.yml

storage-backends:
  groupedfile:                 # the entry key is a FREE unique id (name it anything)
    enabled: true
    type: groupedfile
    path: plugins/EverNifeCore/StorageData/groupedfile
    format: yaml               # yaml | json  (file backends only)
  mysql:
    enabled: false
    type: sql
    url: "jdbc:mysql://localhost:3306/minecraft"
    user: root
    pass: ""
    pool:
      minIdle: 2
      maxSize: 10
      connectTimeoutSeconds: 5
      idleTimeoutSeconds: 30

default-backend: groupedfile   # used when nothing more specific is configured

The entry key is a free unique id, not the type. Declaring several backends of the same type is how you point different data at different servers - e.g. a mysql_economy and a mysql_points, both type: sql, on two databases.

Every backend's runtime dependency (JDBC drivers, the Mongo driver) is downloaded up front at boot, so switching type here never hits a missing dependency.


Supported backends

type: maps to one of these. Full capability matrix and per-backend setup live in the EveryDatabase wiki - the short version:

type: Engine Good for EveryDatabase page
groupedfile key-major files (one file per key, all its collections) the per-player model; the factory default Grouped Files
localfile one file per entity tiny deploys, human-readable Local Files
sql MySQL / MariaDB (HikariCP pool, JSON column) production, shared DB MySQL & MariaDB
postgresql PostgreSQL (HikariCP pool, JSON column) production, shared DB PostgreSQL
h2 H2 embedded / file / tcp embedded / dev H2
mongo MongoDB (native BSON documents) document workloads MongoDB
memory in-memory only, ephemeral tests / throwaway servers In-Memory

format: yaml | json applies to the file backends (groupedfile / localfile) only; yaml is the default and json is always written pretty/indented. For choosing among them, see Choosing a Backend.

⚠️ memory data is lost on shutdown - the parser warns when you enable it. Use it only for tests.


Routing the data

Once backends are declared, three blocks route the actual data. Each may name a storage-backend-id; naming a missing or disabled backend is a fail-fast error at boot with a message that points at the offending key.

playerdata

playerdata:
  storage-backend-id: groupedfile         # must be an enabled backend id
  collection: evernifecore_playerdata
  load-mode: ALL                          # ALL (default) | RECENT
  recent-days: 60                         # RECENT: how far back to eager-load
  login-timeout-seconds: 5                # how long a login may wait on storage before being denied
  orphan-reaper:
    enabled: false                        # opt-in; sweeps section rows whose base is gone
    interval-minutes: 360

load-mode: ALL loads every player at startup; RECENT eager-loads only players seen in the last recent-days and lazy-loads the rest on demand.

pdsections

Generated automatically the first time each PDSection registers - the admin then edits the storage-backend-id, collection and cache of each entry freely (an admin cache: override wins over the developer's cache policy).

multi-platform-accounts

multi-platform-accounts:
  enabled: false
  storage-backend-id: ""      # empty = default-backend

The backend hosting the whole account family (registry + account-wide sections). On a real network it must be a database shared by every instance. See Accounts.


Multi-server cache-sync

When several instances share one database, each instance caches rows independently - a write on instance A must invalidate the same entry on instance B. That is what multi-server-cache-sync does.

multi-server-cache-sync:
  enabled: true               # default; HARMLESS no-op on a single server
  transport: auto             # auto | redis | native
  redis:
    enabled: false
    host: localhost
    port: 6379

Transport resolution:

  • auto (default) - Redis if the redis block is enabled, else the backends' native change feed when every manager's backend has one, else a silent no-op.
  • redis - force the Redis pub/sub transport.
  • native - use only the backends' native feed.

Which backends have a native feed: only MongoDB and PostgreSQL. sql (MySQL/MariaDB) and the file backends do not - for those, cross-instance coherence exists only through Redis.

📌 Current state of the Redis transport. The Redis transport lives in the optional everydatabase-manager-jedis module, which is not bundled with EverNifeCore on this version. If you configure a redis block without that runtime on the classpath, EverNifeCore logs a warning at boot and cache-sync via Redis is a no-op. The native-feed path (Mongo/PostgreSQL) is wired and works today. On a single server the whole block is a harmless no-op regardless.

For the deeper model, see Cross-Process Cache Sync.


Logging

logging:
  level: warn                 # warn (default) | info | debug | trace

Controls the EveryDatabase storage log verbosity (bind reports, conflict/flush lines).


Admin commands: /ecstorage

Subcommand Permission node What it does
status evernifecore.command.storage.status Prints the routing (which backend/collection each entity persists on) plus health counters - quit-flush retry backlog, adopted conflicts, last failed write.
transfer <plugin:section> <backend> evernifecore.command.storage.transfer Migrates one PDSection's collection to another backend at runtime (see below).

Moving data between backends

You are not locked in: a single PDSection's collection can be migrated to another backend at runtime without editing files by hand - see Legacy Data Migration for /ecstorage transfer. The underlying builder is EveryDatabase's Moving Data Between Backends.


See also

Clone this wiki locally