Design notes
The sticky decisions behind beam — idFromName, hibernation, base64 envelopes, kong.
beam is small on purpose. A handful of decisions do most of the work; here's why each one is the way it is.
Name = identity
idFromName(name) makes routing trivially consistent: the Durable Object that
accepted the WebSocket is exactly the one a delivery lands on. There's no
registry mapping names to connections, no pub/sub fan-out layer — the addressing
is the routing. A name maps 1:1 to a DO instance, globally.
Hibernation by default
acceptWebSocket plus a ping/pong auto-response pair means an idle tunnel
isn't pinned in memory. Two payoffs:
- Idle tunnels cost ~nothing — the DO can be evicted while the socket sleeps.
- Reconnects survive eviction — the hibernation API restores the socket cleanly, and the CLI's backoff loop reconnects if anything does drop.
Constant-time token check, before the DO
Auth runs in the Worker, before the upgrade reaches the Durable Object — so failed auth never touches durable state. The comparison is constant-time so the token isn't probeable by timing. See the Security model.
Base64 envelope
Bodies ride inside a JSON frame as base64 so binary payloads survive the WebSocket transport; the CLI decodes and replays verbatim. The trade-off is the WebSocket frame cap (~1 MiB), which bounds payload size — acceptable for webhooks, which are almost always small JSON.
Fire-and-forget v1
The sender gets an immediate 202 and the local response is not relayed back.
Most providers only want a 2xx to mark the webhook delivered, and not waiting on
localhost keeps the edge simple and fast. Round-tripping the real response is
the obvious next step — see the FAQ.
kong for the CLI
The CLI is a kong command struct, with
env-var fallbacks layered under the config file.
That gives a clean beam webhook listen|send <name> tree, generated help, and
the flag > env > config > default precedence for free.
The whole system
One Worker, one Durable Object class, one Go binary. That's the system.
| Decision | Why |
|---|---|
idFromName | Routing == addressing; no registry. |
| Hibernation API | Idle tunnels are free; reconnects survive eviction. |
| Constant-time auth | Token isn't timing-probeable; failures skip durable state. |
| Base64 envelope | Binary-safe payloads over JSON frames. |
| Fire-and-forget | Simple, fast edge; providers only need a 2xx. |
| kong + env + config | One ergonomic CLI, zero-flag in the common case. |