AT-AuctionHouse logoAT-AuctionHouse

Cross-server

Running one shared auction house across a network, what has to be shared and what happens if Redis goes down.

Point several servers at one database and one Redis and they share a single auction house. A player lists an item on survival, another player buys it on skyblock, and both menus update within about a second.

Diagram of three Minecraft servers sharing one MySQL database as the source of truth and one Redis instance carrying sync notifications between them.

What has to be shared

All three of these are required. Getting any one wrong gives you two auction houses that look like one.

Requirement
DatabaseEvery server points DATABASE at the same MySQL or MongoDB. SQLite cannot be shared
RedisEvery server points CROSS-SERVER.REDIS at the same Redis instance
Server IDEvery server has a different CROSS-SERVER.SERVER-ID

Everything else can differ per server. Menus, language, sounds, price bounds and slot limits are all local settings. A network can run a different gui.yml on each server and they still share listings.

Turning it on

Switch the storage backend

SQLite is a single file and cannot be shared. Set DATABASE.TYPE to MYSQL or MONGODB and fill in the connection details. See Storage.

Copy that database block to every server

Byte for byte. If one server points at a different database it silently runs its own auction house.

Enable cross-server mode

CROSS-SERVER:
  ENABLED: true
  SERVER-ID: "survival"
  REDIS:
    HOST: "localhost"
    PORT: 6379
    PASSWORD: ""
    DATABASE: 0
    TIMEOUT: 5000

Give each server its own ID

survival, skyblock, creative, whatever you like, as long as they are all different. The ID appears in /ah about and is attached to every listing, so you can tell where an item was listed.

Restart every server

DATABASE.TYPE is not re-read by /ah reload, so this needs a full restart rather than a reload.

Check it

Run /ah about on each server. It reports the platform, the storage backend and whether cross-server mode is on. Then list something on one server and open /ah on another.

Redis settings

KeyWhat it doesDefault
CROSS-SERVER.REDIS.HOSTRedis hostnamelocalhost
CROSS-SERVER.REDIS.PORTRedis port6379
CROSS-SERVER.REDIS.PASSWORDLeave empty when Redis has no password set""
CROSS-SERVER.REDIS.DATABASERedis database index0
CROSS-SERVER.REDIS.TIMEOUTSocket timeout in milliseconds5000

The connection is tested with a ping at startup rather than assumed. If it fails, the plugin logs the error and carries on as a single server rather than pretending to be connected.

The sync switches

CROSS-SERVER.SYNC controls what actually crosses the wire. All four are on by default.

What crosses the wire

Redis carries small notifications only, on a single channel. A message names its type, the server it came from and one or two arguments, for example "listing 42 sold". No item data and no player inventories travel over Redis.

The message types are listing created, sold, cancelled and expired, cache invalidation, payout available, sale notification, and heartbeat.

Messages a server published itself are ignored on receipt, since it already applied them locally.

The database is the single source of truth. Redis is a notification bus, nothing more. That is what makes the failure mode below so mild.

If Redis goes down

The network keeps working. Every server still reads and writes the same database, so nothing is lost, nothing is duplicated and no sale can go through twice.

What you lose is the fast update:

Still worksDegrades
Listing, buying, cancellingMenus on other servers go stale until refreshed
Money and items moving correctlyCross-server sale notifications stop arriving
Payouts, on the next loginPayouts wait for a login on the right server
Every dupe protectionHeartbeats stop

Players can press the Refresh button in the auction house menu to force a fresh read from the database at any time, which sidesteps the staleness entirely.

If Redis is down when a server starts, that server logs the failure and runs as a single server against the shared database. Restart it once Redis is back.

Dupe protection across servers

Every state change that moves value is a conditional database update rather than a read followed by a write. Two servers trying to sell the same listing at the same moment both issue the same update, and the database lets exactly one of them through. The loser is told the listing is gone.

The collection box works the same way, so an item can be claimed once and only once, on one server only.

Troubleshooting

On this page