GroupeZ Docs

Database

Database architecture, tables, and storage backends for zEssentials

zEssentials uses a relational database to persist all player data, economies, sanctions, vaults, and more. This page covers the available storage backends, the full database schema, performance optimizations, and the migration system.

Storage Backends

Configure the storage-type option in config.yml to select your backend.

ValueBackendRecommended for
SQLITELocal SQLite fileInstallation and tests only
MYSQLMySQL through HikariCPProduction
MARIADBMariaDB through HikariCP (MariaDB driver)Production
HIKARICPMySQL/MariaDB through HikariCPProduction
JSONOne JSON file per playerNot recommended

SQLITE

SQLite is the default backend, storing data in a local file at plugins/zEssentials/database.db. It requires no external database server.

storage-type: SQLITE

SQLite is intended for installation and testing only. Some features are limited (for example, sanction updates when the plugin starts), it uses a single-writer concurrency model, and it cannot be shared between several servers.

Do not use SQLite in production. Switch to MYSQL, MARIADB or HIKARICP before going live.

MYSQL, MARIADB and HIKARICP

These three values connect to a MySQL or MariaDB server. They all use a HikariCP connection pool, which reuses connections, checks their health and evicts stale ones. MARIADB connects with the MariaDB JDBC driver (jdbc:mariadb:), MYSQL and HIKARICP use a jdbc:mysql: URL.

storage-type: HIKARICP

database-configuration:
  table-prefix: "zessentials_"
  host: 192.168.10.10
  port: 3306
  user: homestead
  password: 'secret'
  database: zessentials
  debug: false

The MariaDB JDBC driver is not shaded into the JAR: it is downloaded from Maven Central by Paper when the server starts (see Installation).

Recommended

For any server expecting real players, use HIKARICP (or MARIADB if your server runs MariaDB). It handles concurrent database access efficiently and is required to share data between several servers.

JSON

storage-type: JSON

Player data is stored in one file per player in plugins/zEssentials/users/<uuid>.json. This backend does not support every feature: vaults, the item mailbox, chat history, economy rankings (baltop), transaction and command logs are not available, and data converters cannot be used.

Configuration Reference

PropertyDefault ValueDescription
table-prefixzessentials_Prefix applied to all table names
host192.168.10.10Database server hostname or IP address
port3306Database server port
userhomesteadDatabase username
passwordsecretDatabase password
databasezessentialsDatabase name (must already exist)
debugfalseLogs the executed SQL queries

Always change the default credentials before deploying to production. The values shown above are placeholders only.

Database Tables

zEssentials creates 25 tables (shown below with the default zessentials_ prefix), plus the zessentials_migrations table used to track the applied migrations. Each table is described below with its columns, data types, and purpose.

zessentials_users

Stores core player data. One row per player.

ColumnTypeKeyDescription
unique_idUUIDPKPlayer UUID
nameVARCHAR(16)Current player name
last_locationTEXTSerialized last known location
play_timeBIGINTTotal play time
ban_sanction_idBIGINTID of the active ban in zessentials_sanctions
mute_sanction_idBIGINTID of the active mute in zessentials_sanctions
voteBIGINTTotal vote count
vote_offlineINTVotes received while offline
frozenBOOLEANWhether the player is currently frozen
fly_secondsBIGINTRemaining temporary fly time in seconds
player_timeBIGINTPersonal time set with /ptime (re-applied on join)
player_weatherVARCHAR(32)Personal weather set with /pweather (re-applied on join)
created_atTIMESTAMPAccount first seen
updated_atTIMESTAMPLast data update

zessentials_economies

Stores per-player balances for each economy. Supports multiple currencies.

ColumnTypeKeyDescription
unique_idUUIDPK (composite)Player UUID
economy_nameVARCHARPK (composite)Name of the economy/currency
amountDECIMAL(65,2)Current balance

zessentials_economy_transactions

Logs all economy transactions between players or from the server.

ColumnTypeKeyDescription
from_unique_idUUIDSender player UUID
to_unique_idUUIDReceiver player UUID
economy_nameVARCHAREconomy/currency name
amountDECIMAL(65,2)Transaction amount
from_amountDECIMAL(65,2)Sender balance after transaction
to_amountDECIMAL(65,2)Receiver balance after transaction
reasonTEXTTransaction reason or description

zessentials_user_homes

Stores player home locations.

ColumnTypeKeyDescription
unique_idUUIDPK (composite)Player UUID
nameVARCHARPK (composite)Home name
locationTEXTSerialized location (world, x, y, z, yaw, pitch)
materialVARCHARDisplay icon material for GUI
is_publicBOOLEANWhether the home is public (/homepublic) and can be visited by everyone
categoryVARCHAR(32)Home category (/homecategory)
is_favoriteBOOLEANWhether the home is marked as favorite (/homefavorite)

zessentials_user_home_shares

Stores the homes shared with specific players (/homeshare). Shares are deleted when the home is deleted.

ColumnTypeKeyDescription
owner_idUUIDPK (composite)UUID of the home owner
home_nameVARCHARPK (composite)Name of the shared home
target_idUUIDPK (composite)UUID of the player the home is shared with

zessentials_user_ignores

Stores the players ignored with /ignore (private messages, teleport requests and text mails are blocked).

ColumnTypeKeyDescription
unique_idUUIDPK (composite)UUID of the player who ignores
ignored_idUUIDPK (composite)UUID of the ignored player

zessentials_sanctions

Stores all sanction records (bans, mutes, kicks) with full history.

ColumnTypeKeyDescription
idBIGINTPK (auto increment)Sanction ID
player_unique_idUUIDSanctioned player UUID
sender_unique_idUUIDUUID of the staff member who issued the sanction
sanction_typeVARCHARType of sanction (BAN, MUTE, KICK, etc.)
reasonTEXTReason for the sanction
durationBIGINTDuration in milliseconds
expired_atTIMESTAMPWhen the sanction expires

zessentials_chat_message

Logs chat messages sent by players.

ColumnTypeKeyDescription
unique_idUUIDPlayer UUID
contentTEXTMessage content
created_atTIMESTAMPWhen the message was sent

zessentials_private_messages

Logs private messages between players.

ColumnTypeKeyDescription
sender_unique_idUUIDSender player UUID
receiver_unique_idUUIDReceiver player UUID
contentTEXTMessage content

zessentials_commands

Logs commands executed by players (when enable-command-log is enabled).

ColumnTypeKeyDescription
unique_idUUIDPlayer UUID
commandTEXTFull command string
created_atTIMESTAMPWhen the command was executed

zessentials_user_mail_boxes

Stores items waiting in a player's mailbox (item mailbox).

ColumnTypeKeyDescription
idBIGINTPK (auto increment)Mailbox entry ID
unique_idUUIDRecipient player UUID
itemstackTEXTSerialized ItemStack data
expired_atTIMESTAMPWhen the mailbox item expires

zessentials_user_mail_messages

Stores the text mails sent with /mail send and /mail sendall.

ColumnTypeKeyDescription
idBIGINTPK (auto increment)Mail ID
unique_idUUIDRecipient player UUID
sender_idUUIDSender UUID (null when sent by the console)
sender_nameVARCHAR(36)Sender name
contentTEXTMail content
is_readBOOLEANWhether the mail has been read (/mail read)
created_atTIMESTAMPWhen the mail was sent

zessentials_vaults

Stores vault metadata for player storage vaults.

ColumnTypeKeyDescription
unique_idUUIDPK (composite)Player UUID
vault_idBIGINTPK (composite)Vault number
nameVARCHARCustom vault name
iconTEXTDisplay icon for GUI

zessentials_vault_items

Stores individual items within player vaults.

ColumnTypeKeyDescription
unique_idUUIDPK (composite)Player UUID
vault_idBIGINTPK (composite)Vault number
slotBIGINTPK (composite)Item slot within the vault
itemTEXTSerialized ItemStack data
quantityBIGINTItem stack quantity

zessentials_player_slots

Stores unlocked vault slot data per player.

ColumnTypeKeyDescription
unique_idUUIDPKPlayer UUID
slotsBIGINTNumber of unlocked vault slots

zessentials_user_options

Stores per-player boolean option toggles (vanish, god, social spy, teleport toggles, ping sound...).

ColumnTypeKeyDescription
unique_idUUIDPKPlayer UUID
option_nameVARCHAROption identifier
option_valueBOOLEANCurrent option state

zessentials_user_cooldowns

Stores per-player cooldown timers for commands and features.

ColumnTypeKeyDescription
unique_idUUIDPK (composite)Player UUID
cooldown_nameVARCHARPK (composite)Cooldown identifier
cooldown_valueBIGINTCooldown expiration timestamp in milliseconds

zessentials_user_play_times

Tracks individual play sessions with connection metadata.

ColumnTypeKeyDescription
unique_idUUIDPlayer UUID
play_timeBIGINTSession duration
addressVARCHARPlayer IP address for the session

zessentials_user_power_tools

Stores power tool bindings that map materials to commands.

ColumnTypeKeyDescription
unique_idUUIDPK (composite)Player UUID
materialVARCHARPK (composite)Minecraft material name
commandTEXTCommand to execute on item use

zessentials_steps

Tracks player progression through the steps of the Step module.

ColumnTypeKeyDescription
unique_idUUIDPK (composite)Player UUID
step_nameVARCHARPK (composite)Step identifier
dataJSONArbitrary step data
play_time_startBIGINTPlay time when the step started
play_time_endBIGINTPlay time when the step ended
play_time_betweenBIGINTPlay time spent between start and end
finished_atTIMESTAMPWhen the step was completed (null if in progress)

zessentials_vote_sites

Tracks per-player vote timestamps for each voting site.

ColumnTypeKeyDescription
player_idUUIDPK (composite)Player UUID
siteVARCHARPK (composite)Vote site identifier
last_vote_atTIMESTAMPTimestamp of the last vote on this site

Stores verified Discord-to-Minecraft account links.

ColumnTypeKeyDescription
user_idBIGINTPK (composite)Discord user ID
unique_idUUIDPK (composite)Minecraft player UUID
minecraft_nameVARCHAR(16)Minecraft player name
discord_nameVARCHAR(32)Discord username

Stores temporary linking codes used during the account linking process.

ColumnTypeKeyDescription
codeVARCHARPK (composite)Temporary linking code
user_idBIGINTPK (composite)Discord user ID
discord_nameVARCHAR(32)Discord username

Audit log of all account link and unlink actions.

ColumnTypeKeyDescription
idBIGINTPK (auto increment)History entry ID
actionVARCHARAction type (LINK, UNLINK, etc.)
discord_idBIGINTDiscord user ID
minecraft_idUUIDMinecraft player UUID
discord_nameVARCHAR(32)Discord username at time of action
minecraft_nameVARCHAR(16)Minecraft name at time of action
dataTEXTAdditional action metadata

zessentials_storages

Generic key-value storage for plugin-internal server data.

ColumnTypeKeyDescription
nameVARCHARPKStorage key
contentTEXTSerialized storage value

Unless stated otherwise, most tables also contain created_at and updated_at timestamp columns.

Performance Optimizations

zEssentials implements several layers of write optimization to minimize database load and keep gameplay responsive.

Batch Processing (TypeSafeCache)

Logs and frequent updates are not written to the database one by one. Command logs, chat messages, private messages, economy transactions and fly time updates are accumulated in a TypeSafeCache and flushed to the database in batches at a configurable interval:

batch-auto-save: 10000 # Flush interval in milliseconds

The default flush interval is 10 seconds (10000 ms). This dramatically reduces the number of database round-trips compared to writing each entry individually.

Economy Update Coalescing

Economy balance updates are coalesced per player and per economy with an AtomicReference. When several operations target the same balance in quick succession (e.g. rapid shop transactions), a pending write is reused and only the latest value is persisted. This prevents write amplification while guaranteeing that the database always reflects the correct final balance.

Asynchronous Writes

All other database writes (homes, options, vault items, sanctions...) are executed asynchronously so that the main server thread is never blocked by a database query.

Migration System

zEssentials uses a sequential migration system (provided by the Sarah library) to manage database schema changes across versions. Applied migrations are recorded in the zessentials_migrations table, so only new migrations run on startup.

There are currently 37 registered migrations:

StepMigrations
Core tablesusers, storages, user_options, user_cooldowns, economies, economy_transactions, user_homes
Socialuser_ignores, user_home_shares
Sanctions & logssanctions, ban_sanction_id/mute_sanction_id columns on users, chat_message, commands, user_play_times
Player featuresuser_power_tools, user_mail_boxes, vote/vote_offline columns, vote_sites
Vaultsvault_items, vaults, player_slots
User columnsfrozen, fly_seconds, player_time/player_weather columns on users
Homesis_public, category, is_favorite columns on user_homes
Economyreason column on economy_transactions
Discordlink_codes, link_accounts, link_histories
Refactoringuser_power_tools (v2, composite primary key), player_slots update, private_messages, steps (v2 with play time columns)
Mailboxuser_mail_messages (text mails)

Migrations run automatically on server startup. No manual intervention is required. If you are upgrading from an older version, the plugin applies only the migrations that have not yet been executed.

Never manually modify the migration tracking table or skip migrations. Doing so can leave your database in an inconsistent state. If you encounter migration errors, check the server console for details and report the issue on GitHub or Discord.

On this page

GroupeZ MCP

Documentation in your AI

MCP lets your AI search GroupeZ documentation and read current examples to help you configure your plugins.

Read-only · No documentation API key needed

1. Copy the server URL

Transport: HTTP (Streamable HTTP). Authentication: none. Your tool uses its own model and subscription limits.

  1. Open Plugins in ChatGPT on the web, then + → Add custom MCP server.
  2. Name it ‘GroupeZ Documentation’, paste the URL above and choose ‘No authentication’. Create and install the plugin.
  3. In a conversation, type @ and select the plugin before asking. If needed, enable search, get_page and list_pages in its settings.
Official setup guide

3. Ask a question

Use GroupeZ MCP to help me create a zMenu inventory. Search relevant pages, read the examples and cite your sources.
Other clients and troubleshooting

For clients using mcpServers, adapt this example to their format:

{
  "mcpServers": {
    "groupez-docs": {
      "url": ""
    }
  }
}

Available tools are search, get_page and list_pages. Refresh the connector’s tools after updates. If your AI cannot access them, check that the connector is enabled in the conversation and your account allows custom MCP servers. Opening the URL in a browser is not an MCP test.