PacketRelayDocs

Configuration reference#

PacketRelay is configured entirely at process start: command-line options plus three environment variables. There is no configuration file and no runtime reload. Changing any value below requires a restart, which ends every live session.

Run packet-relay --help on the deployed binary to confirm the options your build accepts. Every option is validated before the listener binds; an out-of-range value prints the failing constraint and exits without starting.

Environment variables#

Variable Effect
PORT Overrides --port when it holds a valid TCP port. Hosted platforms usually inject it.
METRICS_TOKEN Bearer token for GET /metrics. Takes precedence over --metrics-token when it holds a usable value.
RUST_LOG Tracing filter, for example packet_relay=debug. Defaults to packet_relay=info.

Set METRICS_TOKEN through your platform's secret store rather than passing --metrics-token, so the token does not appear in process listings.

Listener and lifecycle#

Option Default Accepted range
--port, -p 8080 Any TCP port. PORT wins.
--session-ttl 300 seconds 30 – 86400
--reaper-interval 30 seconds 1 – --session-ttl
--shutdown-drain 10 seconds 1 – 120

--session-ttl is the age at which a session held by no live connection is reaped. A session with at least one connected participant is never reaped, whatever its age.

--shutdown-drain bounds how long the relay waits for live connections to finish after SIGTERM or Ctrl+C. See Deploy for the platform setting that has to allow that time.

Admission and capacity#

Option Default Accepted range
--max-connections 128 1 – 10000
--max-connections-per-ip 80 1 – --max-connections
--max-connect-rate-per-ip 240 1 – 1000000
--connect-rate-window 60 seconds 1 – 3600
--max-sessions 256 1 – 100000
--max-room-members 32 2 – 256
--max-spectators 64 1 – 1000
--max-id-bytes 64 8 – 256
--hello-timeout 5 seconds 1 – 60

--max-connections-per-ip defaults well above one client because several clients commonly share one NAT address. --hello-timeout bounds two things on every accepted connection: reading the whole HTTP request head, and then the first application frame. It therefore also caps how long a slow /health, /ready, or /metrics request may take, so lower it with that in mind. After admission the heartbeat options below govern liveness instead.

Message limits#

Option Default Accepted range
--max-message-bytes 65536 (64 KiB) 1024 – 65536
--max-messages-per-window 3000 1 – 1000000
--max-bytes-per-window 67108864 (64 MiB) --max-message-bytes – 1 GiB
--message-rate-window 60 seconds 1 – 3600
--outbound-queue 16 messages 1 – 256

--max-message-bytes is both the read ceiling and the largest frame the relay will write. Room traffic is wrapped in a member_frame envelope before it is fanned out, so the usable room payload is smaller than this number — see Protocol.

A connection that exceeds --max-messages-per-window or --max-bytes-per-window receives an error envelope and is then closed with WebSocket code 1008.

Heartbeat and slow consumers#

Option Default Accepted range
--ping-interval 25 seconds 5 – 300
--pong-timeout 10 seconds 1 – --ping-interval
--send-timeout 5 seconds 1 – 60
--slow-consumer-drops 32 1 – 10000

After --ping-interval seconds with no inbound frame the relay sends a WebSocket ping. If nothing arrives within --pong-timeout seconds, the connection is closed with code 4001. Any inbound frame counts as liveness, so a busy connection is never pinged and adds no extra traffic. With the defaults a vanished peer is evicted within 35 seconds, which is inside the idle timeout of the proxies a relay typically sits behind.

--send-timeout bounds one outbound write, whether into a bridge peer's queue or into a client's own socket. --slow-consumer-drops is the number of consecutive fan-out drops a room member or spectator may accumulate before it is closed with code 4002; a single successful delivery resets the run. The relay logs a warning once the run reaches half that threshold.

Important: lowering --pong-timeout or --send-timeout makes the relay intolerant of a briefly slow mobile network. Raise --outbound-queue before loosening either one.

Metrics access#

Option Default Accepted values
--metrics-token unset Non-empty, no whitespace or control characters

While no token is configured, GET /metrics answers 404 and is indistinguishable from any unknown path. Once a token is configured, a scrape must send Authorization: Bearer <token>; anything else receives 401 with WWW-Authenticate: Bearer. See Operations for what the endpoint exposes.

Verify#

  1. Start the relay with the new values and confirm it binds rather than exiting with a validation message.
  2. Check /health and /ready.
  3. Read the Runtime limits configured startup log line, which names the connection, session, message-size, queue, and heartbeat values in effect.
  4. Complete one First bridge round trip.
  5. Exercise the specific limit you changed with a controlled client.

If it does not work#

Symptom Check Recovery
The process exits immediately with a message naming an option A value is outside its accepted range, or violates a cross-option rule such as --pong-timeout exceeding --ping-interval Correct the value to the range in the table above
The relay listens on an unexpected port PORT is set in the environment and overrides --port Unset PORT or set it to the intended port
/metrics returns 404 with a token configured The request target was not exactly /metrics; a query string or a trailing slash makes it an unknown path Scrape the exact path /metrics with no query string
/metrics returns 401 with a token configured The scrape credential does not match the token in effect Scrape with the token named in the environment-variable table above
Clients disconnect with code 4002 under load --outbound-queue is too shallow, or --slow-consumer-drops too low, for the frame rate Raise --outbound-queue first, then re-measure
  • Deploy — where these options are supplied.
  • Protocol — the client-visible effect of the message limits.
  • Operations — monitoring a configured relay.