Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Delivery semantics

This is the contract. What you can rely on. What you must design for.

Online-only, best-effort

  • No persistence: FastPubSub does not store history.
  • Online-only: only listeners that are connected and effectively subscribed at publish time may receive the message.
  • Best-effort: messages can be dropped because of network loss, disconnects, overload, or a slow consumer.

Need guaranteed delivery, replay, or a durable log? Run your own broker beside FastPubSub, or wait for the open-source FastPubSub broker. The overlay itself stays online-only.

Ordering

  • There is no global order across the network.
  • On one connection, frames usually arrive in the order that edge sent them.
  • Across reconnects, regions, or several writers, assume reordering.

If order matters, put a sequence number or timestamp in the payload.

Duplicates

The protocol is not exactly-once. Duplicates can appear after reconnect, application retries, or double processing.

Make consumers idempotent when you can (message id in the payload, local dedup).

Drops and backpressure

If a listener cannot read fast enough, the server protects itself:

  • internal buffers fill,
  • the connection can be closed,
  • that listener can miss messages.

Keep payloads small. Do not block the receive loop. Process work off the socket reader.

Subscribe join window

After subscribe, there is a short window where early publishes may miss the new listener. Nearby servers usually join in a few milliseconds. A long path such as Frankfurt to Australia is typically a few hundred milliseconds (around 400 ms is a realistic far-end case).

Subscribe first. Wait for a subscribe ack when the SDK exposes one. For a critical first message, send a handshake and retry until the listener confirms.

Payload size

One overlay message is 65535 bytes (~64 KB). WebSocket framing uses a few extra bytes for tenant and channel, so a single publish without filters should stay slightly under that.

Larger application payloads are fine if both sides use the SDK FragmentFilter: it splits the payload into several overlay messages and reassembles it on the receiver. Fragments are still best-effort. If some are lost, the assembled message may never complete.

What to assume

  • online-only fan-out
  • best-effort delivery
  • possible reordering
  • possible duplicates
  • possible drops
  • join delay after subscribe
  • path failover in seconds, not instant lossless cutover

See How delivery works for the high-level flow.