Keepalive and timeouts
Keepalive
A pair that sees no traffic for SESSION_TIMEOUT_MINUTES (default 120) is
removed. Pairing again costs a Kyber exchange, so v5 adds an endpoint that
keeps an idle client's pairs alive. v4 had no such endpoint.
POST /api/mte-keepalive
Content-Type: application/json
{"clientId": "<token>", "drop": ["<pairId>", "<pairId>"]}
- One call refreshes the idle timer of every pair the client holds, however many there are.
droplists pairs the client discarded, and the relay deletes them. It may hold at mostMAX_PAIRS_PER_CLIENTids; more is490 invalid_request.- The answer is
{"ok": true, "touched": <count>, "dropped": <count>}. - A token older than
TOKEN_MAX_AGE_SECONDSis answered475 invalid_token, and the client authenticates again. - When the state store cannot be refreshed, the answer is
503 state_store_unavailablewithRetry-After. The client keeps its pairs and retries. - Keepalive is rate limited per client and answered
488 rate_limitedover the limit. See Limits and scaling. - The body counts against
MAX_CONTROL_BODY_MIB.
The clients schedule it for you:
| Client | Keepalive interval |
|---|---|
mte-relay-browser engine | One third of the relay's sessionTimeoutSeconds, clamped to 1 to 10 minutes, unless you set keepAliveIntervalMs. It also pings at once when a hidden browser tab becomes visible again. |
| Outbound relay client (MAR outbound domains) | One third of its SESSION_TIMEOUT_MINUTES, clamped to 1 to 10 minutes. |
With the default 120 minute session timeout both clients ping every 10 minutes.
Deadlines
| Setting | Default | What it bounds |
|---|---|---|
REQUEST_SECONDS | 30 | Silence between request frames, and reading the whole request. Each frame that arrives pushes the deadline out, so a slow upload succeeds as long as it keeps moving. |
IDLE_TIMEOUT_SECONDS | 90 | Silence between response frames. A streaming response, such as server sent events, fails after this long without a byte from the upstream. |
RESPONSE_SECONDS | 0 | The whole response. 0 means no bound beyond the idle deadline. |
HTTP_CLIENT_TIMEOUT_SECONDS | 30 | How long the relay waits for the origin's response headers on inbound domains and pass through routes. On an outbound domain it caps each auth, pair, and keepalive call to the next relay. |
SESSION_TIMEOUT_MINUTES | 120 | Idle lifetime of a pair and of an outbound relay client. |
TOKEN_MAX_AGE_SECONDS | 86400 | Client token lifetime, checked at pair and keepalive. At least 60. |
DRAIN_SECONDS | 30 | Shutdown. How long requests in flight may finish after readiness turns 503. 0 takes the default. |
REQUEST_SECONDS, RESPONSE_SECONDS, and IDLE_TIMEOUT_SECONDS have per
domain overrides in DOMAIN_MAP: request_seconds, response_seconds, and
idle_seconds. Discovery advertises the values that apply to each domain.
The relay also waits at most 10 seconds for a request's headers and closes an idle client keep alive connection after 60 seconds. These are fixed, and SocketX applies the same two timers.
Token refresh
Tokens are checked for age at pair and keepalive, never on the data path. The
outbound relay client refreshes its token at 80 percent of
tokenMaxAgeSeconds, while the token is still valid, so it keeps its client id
and its pairs. The browser engine refreshes only after the relay answers
475 invalid_token. By then the token has aged, so auth issues a new client
id and the engine drops its pairs and pairs again.
Load balancers and proxies
- Streamed responses can be quiet for up to
IDLE_TIMEOUT_SECONDSbetween frames. A load balancer or proxy with a shorter idle timeout closes such a stream first, so raise it for routes that stream. - The relay closes an idle keep alive connection after 60 seconds, a fixed
value. A load balancer that keeps an idle connection to the relay open
longer can send a request on a connection the relay has just closed and
answer it with its own
502. When one idle timeout covers both streams and idle connections, as on an AWS Application Load Balancer, a value above 60 seconds trades occasional502answers for longer quiet streams. - Every framed response carries
X-Accel-Buffering: noandCache-Control: no-store, no-transform, private, so proxies that honor them pass frames through without buffering or caching. - On
SIGTERMa worker turns/readyzto503with phasestoppingfirst. Then the relay listener stops accepting, requests in flight drain for up toDRAIN_SECONDS(30 by default), the relay closes its state store, and the probe listener closes last. A managed worker also sends its goodbye to the control plane inside the same budget, so the fleet view drops it at once. Give the orchestrator a termination grace period aboveDRAIN_SECONDS, or it kills the process before the drain ends. SocketX honorsDRAIN_SECONDSwith the same sequence.
Connection transports
PING_INTERVAL_SECONDS, MAX_PAIR_BYTES, and MAX_PAIR_SECONDS are
advertised for connection transports, such as WebSocket, that share the
protocol. The HTTP relay advertises them and does not act on them.
DRAIN_SECONDS is advertised as the drain window on a connection and is also
the relay's own shutdown budget. The relay still validates that
PING_INTERVAL_SECONDS is below IDLE_TIMEOUT_SECONDS.