Skip to content

Velocity & Redis

Cross-server sync keeps player data in step across a network of backend servers โ€” so a home set on survival-1, a /pay made on survival-2, and a vault filled on the lobby all agree the moment a player switches servers. It is off by default (network.enabled = false); a single server needs none of it and runs purely local.


How It Works

The shared database is the single source of truth. Sync is a lightweight cache-invalidation bus: when one backend changes something, it publishes a small notification โ€” "this player's homes/balance/vault changed, drop your cached copy" โ€” and the other backends re-read the fresh row from the database. A message is never a full record written blindly, so the economy's double-spend guard (an atomic, guarded UPDATE at the database) holds across the whole cluster.

Two things make this work, and both are required:

  1. A shared networked database โ€” MySQL/MariaDB or PostgreSQL โ€” that every backend points at. SQLite cannot be shared; see MySQL / MariaDB.
  2. A transport to carry the notifications between backends: a Velocity proxy broker, a Redis bus, or both.
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚  Velocity   โ”‚   or  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ  โ”‚    Redis     โ”‚
        โ”‚  (broker)   โ”‚                  โ”‚  (pub/sub)   โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜                  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             (backends publish/subscribe)
โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”
โ”‚survivalโ”‚ โ”‚survivalโ”‚ โ”‚ lobby  โ”‚  โ”€โ”€ all read/write โ”€โ”€โ–ถ  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  -1    โ”‚ โ”‚  -2    โ”‚ โ”‚  -1    โ”‚                         โ”‚ shared MySQL โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                         โ”‚  / Postgres  โ”‚
                                                          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

What Syncs

The following stay consistent across every backend:

Synced
Homes Warps
Player warps Economy balances
Vaults Moderation (bans + mutes)
Holograms NPCs
Vote party / counter Messaging ignore lists

Each backend also sends a presence heartbeat so /uxmess doctor can report how many peers are online.


The network Block

Cross-server settings live in the network block of plugins/uxmEssentials/config.conf. These are restart-only โ€” a /uxmess reload does not rewire the bus.

network {
  enabled = false               # opt every backend into the shared bus
  server-id = "server-1"        # MUST be unique per backend
  bus-channel = "uxmessentials:bus_v1"   # plugin-messaging channel; must match the proxy broker
  heartbeat-seconds = 30        # how often this backend announces itself
  transport = "velocity"        # velocity | redis | both

  redis {                       # only used when transport is redis | both
    host = "127.0.0.1"
    port = 6379
    password = ""               # leave empty to skip AUTH
    channel = "uxmessentials:bus"   # every backend must use the same channel
    db = 0                      # logical database index
  }
}
Key Meaning
enabled Turns the shared bus on
server-id This backend's name on the bus โ€” must differ on every backend
bus-channel Plugin-messaging channel for the Velocity path; must match the proxy broker
heartbeat-seconds How often this backend announces its presence (feeds the doctor peer count)
transport How notifications travel: velocity, redis, or both
redis.* Redis connection; the channel must be identical on every backend

Choosing a Transport

Transport You need Best when
velocity (default) The uxmessentials-velocity jar on your Velocity proxy You already run Velocity and want no extra service
redis A Redis server and the uxmEssentials-redis companion jar on each backend You want proxy-independent sync (works behind any proxy)
both Both of the above A mixed network fanning out over both carriers

If the transport is unavailable, the plugin degrades to local-only with a single warning โ€” the individual server keeps working, it just does not sync.


Setup Outline

First, for any transport: provision a shared MySQL/MariaDB or PostgreSQL database, point every backend's storage block at it, and start the backends one at a time on first launch so they do not race the initial Flyway migration.

Velocity path

  1. Drop the uxmessentials-velocity jar onto your Velocity proxy and the main uxmEssentials jar on every backend.
  2. On each backend set enabled = true, transport = "velocity", and a unique server-id.
  3. Leave bus-channel as shipped (it must match the broker).
  4. Restart the proxy, then the backends.

Redis path

  1. Install the uxmEssentials-redis companion jar on every backend, and run a Redis server all backends can reach.
  2. On each backend set enabled = true, transport = "redis", a unique server-id, and point network.redis at the shared Redis with an identical channel.
  3. No proxy is required. Restart the backends.

Verify either path with /uxmess doctor, which shows the active transport, its health, and the number of peers seen.

Every backend must match

All backends must point at the same shared database and use identical economy / currency configuration. A backend on its own SQLite file, or one with a different set of currencies, will not sync correctly โ€” balances and other data can diverge or be rejected. Give every backend a unique server-id; two backends sharing one corrupts sync routing.


Next Steps