Learn · Publish and subscribe

Cursors and checkpoints

Resume a consumer from processed room history, including records it never sees.

A cursor is a subscription's successfully processed position in a room's ordered log. It tells replay where to resume. It is neither a timestamp nor a count of visible messages.

Resume after a position

afterSeq: 42 means scan records with sequences greater than 42. An event advances the SDK cursor after its handler succeeds. A checkpoint advances it after any checkpoint callback succeeds. Both callbacks share the subscription's ordered queue.

The room contains chat at sequence 41, filtered vision at 42, hidden private data at 43, chat at 44, and filtered work at 45. The consumer processes events 41 and 44, then checkpoint 45. It can resume after 45 without rescanning hidden history.
A checkpoint advances through scanned history after earlier visible events are processed.Open SVG ↗Excalidraw source ↓

Here, a chat consumer receives 41 and 44 while the scan also passes other or hidden records. Checkpoint 45 lets it resume beyond the hidden tail. Sequence gaps in a filtered feed are expected.

Save progress with the model it describes

If you restore cursor 500 into an empty message list, replay skips the first 500 records your list might need. Persist the projection and its progress together, or rebuild from zero.

A saved cursor belongs to a specific view: its room, participant, and selection. Reuse it only with the model it describes. If the view expands to include older records, replay from an earlier position.

The projection recipe shows how to save a view and its progress consistently.

Distinguish reconnect from restart

The SDK automatically resumes active consumers after a transient connection loss using their in-memory cursors. A page or process restart requires restoring application-owned progress. After a handler failure or overflow, create a new subscription explicitly from subscription.cursor once the cause is resolved.

The application owns saved progress across restarts. See delivery and recovery for callback failures and how to determine whether replay has caught up.

Use the scanned position for HTTP history

For an HTTP history reader, use the scanned position rather than the last visible event: a page can contain only filtered records. The history example implements that pagination rule.

Read subscription.go, stream.ts, and stream tests for cursor ordering and failure behavior.

Search the documentation

Type to search all guides.

Diagram

100%Open original ↗