The relay is what makes the interface live. Console output, status changes and progress appear as they happen rather than when a browser next asks, and the relay is what carries them.
The relay runs two services side by side:
A service posts a message to the API; the relay fans it out in real time to every client subscribed to those channels.
POST /broadcast
producer ──────────────────────▶ HTTP API
│
▼
client ◀────── Socket.IO ────── Relay server
client ◀────── channel fan-out ──The HTTP API listens on port 2152 by default. The Socket.IO port comes from configuration.
Channels are how a message reaches the right browsers and only those. An instance's console has its own channel, which is why one operator watching a server does not receive another server's output.
Modules do not have to think about this. A child process created with createDefault() is
already wired to its instance's relay channel — that is a large part of what "default" means.
See Service modules.
Two things carry the word relay, and they are not the same:
A node needs 2153 reachable from the panel. That is unrelated to the central relay's own ports. See Ports & firewall.
The relay reads relay.properties from its root directory. Both services can use TLS from a
supplied keystore; the relay validates the password at startup and warns if the certificate is
self-signed.
The symptom is a panel that works but feels dead — actions succeed, status is right after a refresh, and nothing updates on its own.
Check that the relay service is up, that its name resolves and is reachable from the browser rather than only from the panel host, and that the relay record is proxied consistently with the rest if you are behind Cloudflare.