Wake-on-Join - How a Sleeping Free-Tier Server Answers a Player

Wake-on-Join - How a Sleeping Free-Tier Server Answers a Player A sequence diagram generated by Archify. connect · host DNAT 172.96.161.235 → 10.30.0.30 socket is owned by waker (OWN), not wings POST /power start start server proxy the held connection spectator End world + wait ladder docker create container release the socket (hand-off) docker-proxy binds 0.0.0.0:25565 reconnect to the real server no players for 15 min → RESLEEP Arrive Wake Hold Hand-off Re-sleep Player · Minecraft client · Sequence participant Player Minecraft client Host port · 0.0.0.0:25565 · Sequence participant Host port 0.0.0.0:25565 waker · owns ~1232 ports · Sequence participant waker owns ~1232 ports NanoLimbo · 127.0.0.1:30066 · Sequence participant NanoLimbo 127.0.0.1:30066 Panel API · CT102 · Sequence participant Panel API CT102 wings · node001 daemon · Sequence participant wings node001 daemon Game container · docker · Sequence participant Game container docker Legend request return async trace default message

Why the port was free

  • • activity-checker runs hourly and stops servers idle ≥ 2 days
  • • At most 20 stops per pass; customers are warned 24 h ahead
  • • The container exits and releases its host port
  • • Within 30 s the waker binds that port and logs OWN <uuid> :<port>

Gates on the wake

  • • WAKE_RAM_FLOOR_MB=2048 - refuse to boot below this free RAM
  • • WAKE_MAX_CONCURRENT_BOOTS=2 - boot throttle
  • • WAKE_MAX_HOLD_SEC=60 - longest a client sits on the waker socket
  • • WAKE_BOOT_TIMEOUT_SEC=120 - give up waiting for wings to bind

The other way in

  • • If the customer presses Start in the panel instead, the waker tails the wings journal
  • • It spots the start intent and drops the port up front (YIELD)
  • • It stays off that port for 60 s so wings binds first try
  • • node002 runs none of this: paid servers are never auto-slept