From 1c1ecd42f46a7c0875b0737c04f160e2b3a012ea Mon Sep 17 00:00:00 2001 From: Irina Nazarova Date: Wed, 5 Aug 2026 14:22:52 -0700 Subject: [PATCH 1/7] docs: add An Introduction to Realtime Web concept primer --- docs/.vitepress/config.mts | 1 + docs/overview.md | 1 + docs/realtime-web.md | 53 ++++++++++++++++++++++++++++++++++++++ forspell.dict | 1 + 4 files changed, 56 insertions(+) create mode 100644 docs/realtime-web.md diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 09d9119..77b2a33 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -61,6 +61,7 @@ export default withMermaid(defineConfig({ text: 'Start here', items: [ { text: 'What is AnyCable', link: '/overview' }, + { text: 'Intro to realtime web', link: '/realtime-web' }, { text: 'Quick start', link: '/quickstart' }, { text: 'Capabilities', link: '/capabilities' }, { text: '🔥 Troubleshooting', link: '/troubleshooting' }, diff --git a/docs/overview.md b/docs/overview.md index 6e42671..f03de9f 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -90,6 +90,7 @@ configuration, so you can move between them as your needs change. ## Next steps +- [An Introduction to Realtime Web](./realtime-web.md): new to WebSockets, streams, and presence? Start with the concepts. - [Quick Start](./quickstart.md): get a server running and a client connected, by stack. - [Capabilities](./capabilities.md): the features that make AnyCable a realtime framework, not just a transport. - [Using with Rails](./rails/getting_started.md): the Action Cable drop-in path. diff --git a/docs/realtime-web.md b/docs/realtime-web.md new file mode 100644 index 0000000..e713c82 --- /dev/null +++ b/docs/realtime-web.md @@ -0,0 +1,53 @@ +# An Introduction to Realtime Web + +The realtime web is the collection of techniques that let a server deliver +information to a browser the moment something happens, instead of waiting for +the browser to ask for it. This page explains why the web's original +request-response model makes instant delivery difficult, introduces the +transports that overcome that limitation, and surveys the technology that +implements them in production. + +Under the classic HTTP model, communication always begins with the client: the +browser sends a request, the server answers it, and the exchange is complete. +This design scales beautifully for documents, but it leaves the server without +a voice when a new chat message arrives or a delivery driver's location +changes. Early applications worked around the limitation with polling, in +which the browser repeats its request every few seconds, and with long +polling, in which the server holds a request open until it has news to share; +both techniques trade latency for wasted requests. + +A WebSocket removes the limitation at the protocol level. The connection +begins as an ordinary HTTP request, then upgrades into a persistent, +bidirectional channel over which either side may send a message at any time. +Server-Sent Events provide a simpler alternative for information that only +ever flows from server to browser. + +Once a persistent connection exists, applications organize communication with +the publish-subscribe pattern: publishers send messages to a named stream +without knowing who is listening, subscribers declare which streams interest +them, and a broker performs the fan-out. A broadcast delivers one message to +every subscriber of a stream, and presence tracks who is currently connected, +which requires heartbeats because networks drop without saying goodbye. +Delivery guarantees decide what happens after such a drop: dependable systems +keep a short history of each stream so that a returning client receives the +messages it missed, in order. + +The technology comes in three families. Web frameworks ship realtime layers +that run inside the application process, such as Action Cable in Rails, +Channels in Phoenix, Reverb in Laravel, and Socket.IO in Node.js; they are the +easiest way to start, and because the application holds every connection, a +deploy disconnects every user. Managed services such as Pusher and Ably hold +the connections in their cloud instead and charge per message. Dedicated +realtime servers, such as [AnyCable](./overview.md) and Centrifugo, run next +to your application and own the connections: AnyCable works with Rails, +Laravel, Node.js, Python, and any HTTP backend, implements +[presence](./anycable-go/presence.md), +[JWT authentication](./anycable-go/jwt_identification.md), and +[reliable streams](./anycable-go/reliable_streams.md) that restore missed +messages after a disconnect, and holds +[over 800,000 connections](https://anycable.io/compare/nodejs-websocket/) per +instance while application deploys leave live connections untouched. + +To see these concepts as working code, continue with the +[Quick Start](./quickstart.md), or read [What is AnyCable](./overview.md) and +[Capabilities](./capabilities.md) for how each guarantee is implemented. diff --git a/forspell.dict b/forspell.dict index 43e040c..b1bd3db 100644 --- a/forspell.dict +++ b/forspell.dict @@ -7,6 +7,7 @@ AnyCable Balancer Broadcasted Browserslist +Centrifugo Datadog Disconnector Dockerfile From 6a65ea15b1efd2c8a79ba6635efaf3974ad18475 Mon Sep 17 00:00:00 2001 From: Irina Nazarova Date: Wed, 5 Aug 2026 14:31:05 -0700 Subject: [PATCH 2/7] docs: add Key terms definitions to the realtime web primer --- docs/realtime-web.md | 37 +++++++++++++++++++++++++++++++++++++ forspell.dict | 1 + 2 files changed, 38 insertions(+) diff --git a/docs/realtime-web.md b/docs/realtime-web.md index e713c82..7262f16 100644 --- a/docs/realtime-web.md +++ b/docs/realtime-web.md @@ -48,6 +48,43 @@ messages after a disconnect, and holds [over 800,000 connections](https://anycable.io/compare/nodejs-websocket/) per instance while application deploys leave live connections untouched. +## Key terms + +The vocabulary of realtime systems, with each term defined so it can stand on +its own. These are the definitions used throughout the AnyCable documentation. + +- A **WebSocket** is a connection that begins as an ordinary HTTP request and + upgrades into a persistent, bidirectional channel, allowing the client and + the server to send messages to each other at any time. +- **Server-Sent Events (SSE)** is a browser standard in which the server keeps + an HTTP response open and pushes a one-directional stream of events to the + client, suitable for feeds that never need to flow the other way. +- **Publish-subscribe (pub/sub)** is a messaging pattern that decouples senders + from receivers: publishers send messages to named streams without knowing the + audience, and a broker delivers each message to every subscriber of that + stream. +- A **stream** is a named feed of messages, such as `chat/42`, that clients + subscribe to and backends publish to; the stream name is the address that + connects the two. +- A **broadcast** is the act of publishing one message to a stream so that + every subscribed client receives its own copy. +- **[Presence](./anycable-go/presence.md)** is the live roster of clients + subscribed to a stream, kept accurate through heartbeats and expiry, and + delivered to applications as join and leave events. +- A **[signed stream](./anycable-go/signed_streams.md)** is a stream name + accompanied by a cryptographic signature that the application generates with + a secret key, letting a realtime server such as AnyCable authorize the + subscription by verifying the signature instead of calling the application. +- A **[reliable stream](./anycable-go/reliable_streams.md)** is a stream whose + recent history the server retains, so that a client reconnecting after a + network drop receives every message it missed, in the original order. +- A **[whisper](./js/presence.md)** is a message that one client sends directly + to the other subscribers of a stream through the realtime server, without + involving the backend application; typing indicators and live cursor + positions are typical whispers. + +## Where to go next + To see these concepts as working code, continue with the [Quick Start](./quickstart.md), or read [What is AnyCable](./overview.md) and [Capabilities](./capabilities.md) for how each guarantee is implemented. diff --git a/forspell.dict b/forspell.dict index b1bd3db..6b30af2 100644 --- a/forspell.dict +++ b/forspell.dict @@ -8,6 +8,7 @@ Balancer Broadcasted Browserslist Centrifugo +cryptographic Datadog Disconnector Dockerfile From f696e986b5f30181cafda4429e48c1757196b8bb Mon Sep 17 00:00:00 2001 From: Irina Nazarova Date: Wed, 5 Aug 2026 14:34:28 -0700 Subject: [PATCH 3/7] docs: define delivery semantics and connection state recovery in Key terms --- docs/realtime-web.md | 17 +++++++++++++++++ forspell.dict | 1 + 2 files changed, 18 insertions(+) diff --git a/docs/realtime-web.md b/docs/realtime-web.md index 7262f16..02b4480 100644 --- a/docs/realtime-web.md +++ b/docs/realtime-web.md @@ -68,6 +68,23 @@ its own. These are the definitions used throughout the AnyCable documentation. connects the two. - A **broadcast** is the act of publishing one message to a stream so that every subscribed client receives its own copy. +- **At-most-once delivery** is the default semantics of a plain WebSocket and + of most realtime tools, including Socket.IO and Pusher: each message is sent + a single time, and a message published while a client's connection is broken + is silently lost. +- **At-least-once delivery** guarantees that every message eventually reaches + its subscriber, which the sender achieves by keeping each message until + receipt is acknowledged and retrying when it is not; the price is that a + receiver must tolerate an occasional duplicate. Socket.IO offers this as an + opt-in through acknowledgments and its retries option. +- **Exactly-once delivery** guarantees that every message arrives, and arrives + a single time, which requires deduplication on top of retries; Ably + implements it by assigning every message a unique serial number and + discarding any resend whose serial it has already seen. +- **Connection state recovery** is Socket.IO's name for restoring a briefly + disconnected client's state, including its subscriptions and the events it + missed; Ably calls the same idea resuming a connection, and AnyCable + provides it through reliable streams backed by the server's stream history. - **[Presence](./anycable-go/presence.md)** is the live roster of clients subscribed to a stream, kept accurate through heartbeats and expiry, and delivered to applications as join and leave events. diff --git a/forspell.dict b/forspell.dict index 6b30af2..922b627 100644 --- a/forspell.dict +++ b/forspell.dict @@ -9,6 +9,7 @@ Broadcasted Browserslist Centrifugo cryptographic +deduplication: duplication Datadog Disconnector Dockerfile From bd705ee41e5da245eb721a4fffa79bf8a6f6a606 Mon Sep 17 00:00:00 2001 From: Irina Nazarova Date: Wed, 5 Aug 2026 14:35:57 -0700 Subject: [PATCH 4/7] docs: credit AnyCable with exactly-once delivery in Key terms --- docs/realtime-web.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/realtime-web.md b/docs/realtime-web.md index 02b4480..1cf25f1 100644 --- a/docs/realtime-web.md +++ b/docs/realtime-web.md @@ -78,9 +78,12 @@ its own. These are the definitions used throughout the AnyCable documentation. receiver must tolerate an occasional duplicate. Socket.IO offers this as an opt-in through acknowledgments and its retries option. - **Exactly-once delivery** guarantees that every message arrives, and arrives - a single time, which requires deduplication on top of retries; Ably - implements it by assigning every message a unique serial number and - discarding any resend whose serial it has already seen. + a single time, which requires deduplication on top of retries. Ably + implements it by assigning every message a unique serial number, and + AnyCable achieves it through its server and client SDK working together: + every broadcast in a reliable stream carries an incrementing offset, and a + reconnecting client resumes from the last offset it saw, with neither a gap + nor a repeat. - **Connection state recovery** is Socket.IO's name for restoring a briefly disconnected client's state, including its subscriptions and the events it missed; Ably calls the same idea resuming a connection, and AnyCable @@ -94,7 +97,9 @@ its own. These are the definitions used throughout the AnyCable documentation. subscription by verifying the signature instead of calling the application. - A **[reliable stream](./anycable-go/reliable_streams.md)** is a stream whose recent history the server retains, so that a client reconnecting after a - network drop receives every message it missed, in the original order. + network drop receives every message it missed, in the original order; + paired with the AnyCable client SDK, it upgrades delivery from at-most-once + to exactly-once. - A **[whisper](./js/presence.md)** is a message that one client sends directly to the other subscribers of a stream through the realtime server, without involving the backend application; typing indicators and live cursor From 0d4800e2bf59e45e3c6bd1f8fb84b564688e72f8 Mon Sep 17 00:00:00 2001 From: Irina Nazarova Date: Wed, 5 Aug 2026 14:36:52 -0700 Subject: [PATCH 5/7] docs: define reconnection avalanche, RPC, and broker in Key terms --- docs/realtime-web.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/realtime-web.md b/docs/realtime-web.md index 1cf25f1..2d593c2 100644 --- a/docs/realtime-web.md +++ b/docs/realtime-web.md @@ -88,6 +88,13 @@ its own. These are the definitions used throughout the AnyCable documentation. disconnected client's state, including its subscriptions and the events it missed; Ably calls the same idea resuming a connection, and AnyCable provides it through reliable streams backed by the server's stream history. +- A **reconnection avalanche** (also known as a thundering herd) happens when + a restart or network incident disconnects thousands of clients at once and + they all try to reconnect at the same moment, hitting the servers hardest + exactly when they are weakest. Clients defend against it by reconnecting + with exponential backoff and random jitter, which the AnyCable client SDK + applies by default, and servers defend by spreading disconnects over the + shutdown period, a mode AnyCable Pro calls slow drain. - **[Presence](./anycable-go/presence.md)** is the live roster of clients subscribed to a stream, kept accurate through heartbeats and expiry, and delivered to applications as join and leave events. @@ -95,11 +102,20 @@ its own. These are the definitions used throughout the AnyCable documentation. accompanied by a cryptographic signature that the application generates with a secret key, letting a realtime server such as AnyCable authorize the subscription by verifying the signature instead of calling the application. +- **[RPC](./anycable-go/rpc.md)** (remote procedure call) is the integration + mode in which the realtime server delegates decisions to the application: + when a client connects, subscribes, or performs an action, AnyCable calls + the application code and applies its verdict, which is how existing Rails + Action Cable channels work with AnyCable unchanged. - A **[reliable stream](./anycable-go/reliable_streams.md)** is a stream whose recent history the server retains, so that a client reconnecting after a network drop receives every message it missed, in the original order; paired with the AnyCable client SDK, it upgrades delivery from at-most-once to exactly-once. +- The **[broker](./anycable-go/broker.md)** is the component of a realtime + server that keeps recent stream history and session state in a short-lived + cache, turning a bare transport into a delivery system; AnyCable's built-in + broker is what makes reliable streams and resumable sessions possible. - A **[whisper](./js/presence.md)** is a message that one client sends directly to the other subscribers of a stream through the realtime server, without involving the backend application; typing indicators and live cursor From b5139f016dc316c2a7bdfdae6f9408a50a675242 Mon Sep 17 00:00:00 2001 From: Irina Nazarova Date: Wed, 5 Aug 2026 14:37:30 -0700 Subject: [PATCH 6/7] docs: define JWT in Key terms --- docs/realtime-web.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/realtime-web.md b/docs/realtime-web.md index 2d593c2..72eebae 100644 --- a/docs/realtime-web.md +++ b/docs/realtime-web.md @@ -98,6 +98,12 @@ its own. These are the definitions used throughout the AnyCable documentation. - **[Presence](./anycable-go/presence.md)** is the live roster of clients subscribed to a stream, kept accurate through heartbeats and expiry, and delivered to applications as join and leave events. +- A **[JWT](./anycable-go/jwt_identification.md)** (JSON Web Token) is a + compact token, cryptographically signed by its issuer, that encodes claims + such as a user's identity so that any party holding the matching key can + verify them without a database lookup. In realtime systems the application + issues a JWT and the realtime server verifies it during the handshake, + authenticating the connection without calling the application. - A **[signed stream](./anycable-go/signed_streams.md)** is a stream name accompanied by a cryptographic signature that the application generates with a secret key, letting a realtime server such as AnyCable authorize the From 39070748c088da35d7adfe2197ffefa354f98fcc Mon Sep 17 00:00:00 2001 From: Irina Nazarova Date: Wed, 5 Aug 2026 14:40:46 -0700 Subject: [PATCH 7/7] docs: qualify the connections benchmark as idle and credit broker with presence --- docs/realtime-web.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/realtime-web.md b/docs/realtime-web.md index 72eebae..c2c28dd 100644 --- a/docs/realtime-web.md +++ b/docs/realtime-web.md @@ -45,8 +45,8 @@ Laravel, Node.js, Python, and any HTTP backend, implements [JWT authentication](./anycable-go/jwt_identification.md), and [reliable streams](./anycable-go/reliable_streams.md) that restore missed messages after a disconnect, and holds -[over 800,000 connections](https://anycable.io/compare/nodejs-websocket/) per -instance while application deploys leave live connections untouched. +[over 800,000 idle connections](https://anycable.io/compare/nodejs-websocket/) +per instance while application deploys leave live connections untouched. ## Key terms @@ -119,9 +119,10 @@ its own. These are the definitions used throughout the AnyCable documentation. paired with the AnyCable client SDK, it upgrades delivery from at-most-once to exactly-once. - The **[broker](./anycable-go/broker.md)** is the component of a realtime - server that keeps recent stream history and session state in a short-lived - cache, turning a bare transport into a delivery system; AnyCable's built-in - broker is what makes reliable streams and resumable sessions possible. + server that keeps recent stream history, session state, and presence + information in a short-lived cache, turning a bare transport into a delivery + system; AnyCable's built-in broker is what makes reliable streams and + resumable sessions possible. - A **[whisper](./js/presence.md)** is a message that one client sends directly to the other subscribers of a stream through the realtime server, without involving the backend application; typing indicators and live cursor