OptionalauthA Restate Cloud API key with the Full role (key_...), or a user
JWT. Presented as authorization: Bearer <token> during the tunnel
handshake; validated server-side.
Falls back to the contents of the file named by the
RESTATE_INPROC_AUTH_TOKEN_FILE environment variable — the right shape
for a mounted Kubernetes Secret: the file is re-read on every reconnect,
so a rotated token is picked up without a restart.
OptionalbidirectionalProtocol mode for the SDK handler. Default true (BIDI_STREAM) —
the tunnel is always HTTP/2, so full-duplex streaming is available.
OptionalconnectionPer-connection HTTP/2 flow-control window in bytes. Default 16 MiB (Node's 64 KiB default throttles aggregate throughput).
OptionalconnectDeadline for establishing the TCP connection and completing the TLS handshake. Default 5_000 (mirrors the standalone tunnel client's connect timeout). Without it, a peer that accepts the connection but never completes TLS would stall reconnection indefinitely.
OptionaldefaultDefault service options that will be used by all services bind to this endpoint.
Options can be overridden on each service/handler.
OptionaldrainHow long a draining connection may keep serving its in-flight invocations before being torn down. Default 120_000 (mirrors the standalone tunnel client).
OptionalenvironmentThe Restate Cloud environment ID to tunnel to, including the env_
prefix (e.g. "env_201k0yd4rz8yftmd4awh1bajg4v").
Falls back to the RESTATE_INPROC_ENVIRONMENT_ID environment variable.
OptionalgracefulAutomatic graceful shutdown on process signals. On by default: the
engine installs a one-shot handler for each signal (default SIGTERM)
that calls TunnelConnection.shutdown. If multiple tunnels in the
same process register for a signal, the shared process-level handler waits
for all of them before calling process.exit(0) once draining completes
(or the grace elapses) — so an operator-managed deployment gets
zero-dropped-invocation rollouts with no wiring. In Kubernetes, set
terminationGracePeriodSeconds to at least the drain grace plus the
handler slack you want to preserve. The handlers are removed when the
connection closes.
Pass false to opt out entirely — e.g. to manage signals and process
exit yourself and call TunnelConnection.shutdown by hand. Pass an
object to choose the signals and grace, or true for the defaults.
OptionalhandshakeDeadline for the tunnel handshake (the server opening
/_/start-tunnel and completing it with trailers). Default 5_000,
mirroring the tunnel server's own handshake timeout.
Optional ExperimentaljournalProvider for the codec to use for journal values. One codec will be instantiated globally for this endpoint. Check JournalValueCodec for more details
OptionalloggerReplace the default console-based LoggerTransport
Using console:
createEndpointHandler({ logger: (meta, message, ...o) => {console.log(`${meta.level}: `, message, ...o)}})
OptionalmaxMaximum concurrent HTTP/2 streams (in-flight invocations) per connection. Default 4096 (Node's default of 100 is far too low for a deployment serving many concurrent invocations).
OptionalmaxNode http2 per-session memory cap in MiB. Default 256 (Node's 10 MiB default makes the session reject work under load).
OptionalpingLiveness watchdog: send an HTTP/2 PING every this many milliseconds. Default 75_000 (the tunnel protocol's keepalive cadence).
OptionalpingWatchdog: consecutive missed PINGs before the connection is declared dead and redialed. Default 2.
OptionalpingWatchdog: how long to wait for a PING ack. Default 10_000.
OptionalreconnectReconnect backoff policy: jittered exponential backoff applied between reconnect attempts (10ms → 120s by default), reset after a stable connection. See ReconnectRetryPolicy.
OptionalregionRestate Cloud region (e.g. "us", "eu"). Tunnel servers are
discovered via a DNS SRV lookup of tunnel.<region>.restate.cloud,
expanded to every resolved address — the engine holds one tunnel
connection per resolved tunnel server (like the standalone client),
and re-resolves every resolveIntervalMs, starting connections
to servers that appear and tearing down connections to servers that
vanish.
Exactly one of region, tunnelServersSrv or tunnelServers must be
set. When none is, region falls back to the
RESTATE_INPROC_CLOUD_REGION environment variable.
OptionalresolveHow often region-based discovery re-resolves the tunnel-server set.
Default 30_000. (The Rust client re-resolves on DNS TTL expiry; Node
does not expose record TTLs, so a fixed interval approximates it.)
Ignored with explicit tunnelServers.
A list of Restate services, virtual objects, or workflows that will be exposed via the endpoint.
OptionalsignalAbort to stop reconnecting and close the tunnel (same as close()).
OptionalsigningThe environment's request-identity public key
(publickeyv1_<base58>). Passed to the SDK's request-identity
verification so every forwarded request is checked to genuinely come
from your environment. Shown by Restate Cloud for your environment.
Falls back to the RESTATE_INPROC_SIGNING_PUBLIC_KEY environment
variable.
OptionalstartupOptional one-shot startup readiness gate. Without this option the tunnel dials immediately, preserving the previous behavior. When supplied, the tunnel supervisor waits for this promise or callback to complete before dialing any tunnel server, so the server cannot select this worker until the local in-process handler is ready. If the gate rejects, throws, or does not complete within startupReadyTimeoutMs, the tunnel stops and TunnelConnection.ready rejects.
This is the startup counterpart to supportsClientDrain: startup gates traffic until the handler is ready; shutdown drain removes the connection from selection before the handler stops.
OptionalstartupDeadline for startupReady. Default 120_000. Only used when
startupReady is supplied; a stuck startup gate is treated as fatal so a
broken worker is visible instead of silently absent from the tunnel fleet.
OptionalsupportsAdvertise client-initiated graceful drain (supports-client-drain: true)
in the handshake. Default true. When enabled, TunnelConnection.shutdown (or the default gracefulShutdown signal
handler) proactively sends HTTP/2 GOAWAY and refuses any raced streams
with a drain sentinel, so Restate Cloud stops routing new work to this
process while its in-flight invocations finish — the basis for
zero-dropped-invocation rollouts. Specific to this in-process client; the
standalone Rust client does not implement it.
OptionalsupportsAdvertise graceful-drain support (supports-drain: true) in the
handshake. Default true. When Restate Cloud rolls a tunnel node it
sends /_/drain-tunnel to drain-capable connections: the engine then
immediately opens a replacement connection while the old one keeps
serving its in-flight invocations (bounded by drainGraceMs) —
zero dropped requests across cloud rollovers. With false, the cloud
simply closes the connection and in-flight invocations are retried by
the Restate runtime after the redial.
OptionaltlsTLS for the outbound connection. Default true (system trust, SNI =
dialed host, ALPN h2). Pass false only for plaintext dev/test setups,
or an object for a private CA / mTLS.
OptionaltunnelDiagnostic logger. Default: silent.
OptionaltunnelThe deployment's identity: the rendezvous key both ends use to route.
The tunnel server keys connections by <environment>/<tunnelName> and
load-balances each proxied invocation across every connection
registered under that key — so replicas of the same deployment must
share one tunnelName, and distinct deployments must each have their
own. It appears in the deployment registration URL, so it should be
stable across restarts (e.g. "greeter-v1").
Falls back to the RESTATE_INPROC_TUNNEL_NAME environment variable
(the restate-operator injects a per-revision name there).
OptionaltunnelExplicit tunnel server addresses, instead of region-based discovery.
Each entry is either "host:port" (TLS governed by the tls option)
or a URL "https://host:port" / "http://host:port" (scheme selects
TLS/plaintext for that server). The engine holds one tunnel connection
per entry; the set is fixed (no re-resolution).
Exactly one of region, tunnelServersSrv or tunnelServers must be
set.
OptionaltunnelA DNS SRV name to discover tunnel servers from, for environments whose
SRV name doesn't follow the tunnel.<region>.restate.cloud template
(the standalone client's RESTATE_TUNNEL_SERVERS_SRV). Same expansion
and reconciliation semantics as region.
Exactly one of region, tunnelServersSrv or tunnelServers must be
set.
OptionaltunnelStable diagnostic identifier for this SDK worker/process. The tunnel
server can include it in routing and failure logs so operators can grep
server-side events against SDK-side logs. Defaults to
RESTATE_TUNNEL_WORKER_ID when set, otherwise a hostname-based id with a
short random suffix that is stable for this process. Advisory only: it is
sent in the tunnel handshake for diagnostics, not used for authentication.
Options for connectTunnel.
The identity and discovery options fall back to
RESTATE_INPROC_*environment variables when not given (option > environment > throw):tunnelName←RESTATE_INPROC_TUNNEL_NAME,environmentId←RESTATE_INPROC_ENVIRONMENT_ID,region←RESTATE_INPROC_CLOUD_REGION,signingPublicKey←RESTATE_INPROC_SIGNING_PUBLIC_KEY, andauthToken← the file named byRESTATE_INPROC_AUTH_TOKEN_FILE(re-read on every reconnect, so rotations are picked up). The restate-operator injects the first four into the pods of atunnelMode: in-processRestateDeployment and registers the matching URL — there,connectTunnel({ services })plus a token-file Secret mount (named byRESTATE_INPROC_AUTH_TOKEN_FILE) is a complete configuration.