Skip to main content
How to keep local state consistent across reconnects: enabling recovery, reading the subscribed outcome, deduplicating replayed messages, and fetching history. Per-namespace history settings are on Channel and limit reference; the snapshot-plus-subscribe seed pattern is on Initialization.

Enabling recovery

Pass options to newSubscription to control reliability behavior: Set recoverable: true on channels whose namespace has history.

Interpreting subscribed after reconnect

After a reconnect, the subscribed event fires with context that tells you whether your local state is still consistent:
  • wasRecovering: the client attempted to recover from a previous stream position
  • recovered: the server successfully replayed all missed publications
  • positioned: the subscription has stream position tracking enabled
  • recoverable: the subscription supports automatic recovery

Delivery guarantees

For namespaces with history enabled, Centrifugo provides at-least-once delivery within the recovery window — missed messages are replayed from server-side history on reconnect. When recovered: true, everything you missed was replayed and you do not need to re-seed from REST. If the disconnect outlasts it (or the message cap is reached first), wasRecovering: true, recovered: false fires and you must re-seed from REST. Recovery can fail even after a short disconnect if the server no longer has the missed publications in history or if the saved stream position is no longer valid. When this happens recovered is false and you must re-seed from REST.

Dedup

At-least-once delivery means a message may occasionally be replayed more than once during recovery. Every publication includes a messageId in ctx.tags — use it to deduplicate on the client side:
messageId deduplicates any repeated publication, whatever the cause. There is no separate handling for recovery replay versus other duplicates — one messageId per publication, drop the ones you have already seen.
orderbook_v3 and orderbook_v3_event are the exception: their version both orders and de-duplicates the book. Apply a publication only when its version is strictly greater than the one you hold for that market — you do not need messageId there. See each channel’s reference.

History

Each namespace with history enabled maintains a server-side log of recent publications. You can fetch this directly with sub.history() — useful for seeding initial state or auditing recent activity without a separate REST call.

Parameters

The response contains a publications array and the current stream offset and epoch. Each entry has data, offset, tags, and info fields — access the payload via pub.data, the same as ctx.data in a live publication event.

Limits

History fetches are bounded by the per-namespace caps in Channel and limit reference and the global limit of 1,000 items per request. Calling sub.history() on a channel with no history enabled returns error code 108. orderbook_v3 keeps one message as a cache rather than a log, so the client is not granted history there. For the snapshot-plus-subscribe seed pattern, see Initialization → Snapshot + subscribe pattern.

Real-time data →

The guide with full worked examples, channel reference, and common failures.
Last modified on August 11, 2026