- Compare
- /
- Ably vs Pusher
- /
- Ably vs Pusher deep dive: message ordering and connection recovery compared
Ably vs Pusher deep dive: message ordering and connection recovery compared
Ably and Pusher offer the same developer-facing primitives: channels, presence, and a publish/subscribe API. Where they differ is in what happens when something goes wrong at scale — and it is also where Pusher's own documentation is most direct about what it does and does not promise.
This page covers four properties in detail: message ordering, exactly-once delivery, message history and replay, and the message size constraints that interact with all three. It is most relevant for chat applications with unreliable mobile clients, financial or operational data feeds where event order matters, and AI products that stream agent or model output to a UI.
For a side-by-side feature table covering pricing, security, and infrastructure, see the Ably vs Pusher feature comparison.
Key takeaways
Pusher's own documentation states it cannot guarantee message order or delivery, because messages are processed in parallel across its backend with no path to replay what a client missed.
Ably guarantees ordered delivery and exactly-once semantics per channel for realtime publishers in the same region, using a unique incrementing serial assigned to every message.
Pusher offers no message history by default; its Cache Channels feature stores only the single most recent event per channel for up to 30 minutes, which is a state snapshot, not a replay mechanism.
A 10KB hard message limit on Pusher, combined with no ordering or delivery guarantee, makes Pusher's architecture a poor fit for streaming structured output like LLM tokens, where order and completeness both matter.
How each platform is built
The behaviors covered on this page all trace back to one architectural decision each platform made early on. Understanding that decision makes every guarantee, and every gap, predictable rather than arbitrary.
Pusher's architecture: parallel processing, no central order
Pusher's Channels product spreads message processing across many backend machines in parallel, so no single point tracks the order that messages arrive in. This favors throughput: no single component is a bottleneck, and the system scales by adding machines. But once a message is sent, it's gone: nothing stores it for later.
Pusher's own documentation confirms this directly. The same design explains the lack of default message history: there's no central log to query, only a live broadcast to whoever's connected when a message is sent.
These are not gaps awaiting a fix. Pusher has been in active maintenance since its acquisition by MessageBird (now Bird) in December 2020, with no new features shipped and no public roadmap.
Ably's architecture: ordered, replicated, and serial-tracked
Ably's platform assigns every message a unique, time-based incrementing serial number when it is accepted. That serial number is what enables:
Ordering, so subscribers receive messages in the exact sequence they were published
Deduplication, so a duplicate is detected and discarded if a publisher retries after a failed acknowledgment
Replay, so a reconnecting client can tell Ably exactly where it left off, and only what was missed gets resent
Ably also runs a globally distributed architecture. A message is first received by the region closest to the publisher, then distributed to every other region where the channel is active. It is also persisted, so it can be queried later through the History API.
This is a more complex system to operate than Pusher's. Ably's documentation is direct about the tradeoff: ordering and replication are guaranteed for a given publisher on a given channel, not as a strict global sequence across every publisher everywhere. The message ordering section below explains what that distinction means in practice.
Compare Ably and Pusher on delivery guarantees
"Delivery guarantees" isn't a single property. It spans four related but distinct concerns, and a platform strong on one can fall short on another.
Message ordering
Ordering is whether subscribers receive messages in the sequence they were published, rather than in whatever sequence happens to arrive over the network.
Pusher does not guarantee it, for the architectural reason covered above: parallel backend processing means there is no single point tracking sequence across messages. The one documented exception is a single batch publish call, where Pusher preserves the order of events within that batch. Outside of batching, Pusher's own recommended workaround is for the developer to attach an increasing sequence ID to every message and reorder them on the client.
Ably guarantees ordering using the serial assigned to every message. For a single publisher sending messages on a channel, subscribers connected via Ably's Realtime libraries receive those messages in the exact order they were published, with no application code required to achieve it.
The condition worth stating plainly: this is a per-publisher, per-channel guarantee, which Ably calls "realtime order." It holds cleanly for the large majority of production use, since most channels have exactly one publisher. Ably also maintains a separate "canonical global order" used when retrieving message history, which is consistent regardless of region.
Exactly-once delivery
Exactly-once delivery means a message published once is delivered to each subscriber precisely once, even after a failed acknowledgment forces a retry. It is one of the harder properties to engineer in a distributed pub/sub system, since the publisher, broker, and subscriber can each fail independently, and a naive retry risks delivering a duplicate.
Pusher does not offer this guarantee. A publisher that retries after a failed acknowledgment has no platform-level mechanism to avoid sending the same message twice, and no built-in way for a subscriber to detect that a duplicate has arrived.
Ably implements exactly-once using the same unique serial number assigned to every message on acceptance. If a publisher resends after a failed acknowledgment, Ably recognizes the resend by its serial and discards the duplicate rather than delivering it again. The same mechanism works in reverse for a reconnecting subscriber. The client reports the serial number of the last message it received, and Ably resumes from that exact position, with neither a gap nor a repeat.
This guarantee covers what happens once a message reaches Ably. It only holds end-to-end if every other component in the pipeline plays its part too.
Message history and reconnect replay
History and replay is whether a client that was disconnected, even briefly, can catch up on what it missed, or whether those messages are simply gone.
Pusher offers no message history by default. The closest built-in feature, Cache Channels, stores only the single most recent event published to a channel. It holds that one event for a maximum of 30 minutes, and then it's gone. A client that missed ten messages and then subscribes to a Cache Channel receives the latest one; the nine before it are gone. This is a last-value snapshot for showing the current state on initial load, not message history.
For real catch-up, you have to build and maintain your own message store. That means a database to store every message, sequence tracking per client, a fetch-on-reconnect endpoint, deduplication, and reordering. All of it runs alongside Pusher rather than being provided by it.
Ably provides two complementary mechanisms covering different time horizons. For short disconnections (e.g. a tunnel, a backgrounded mobile app, or a brief network drop), a client that reconnects within two minutes gets every missed message replayed, in order. The same exactly-once guarantee that applies to live delivery applies here too, with no application code required to trigger it.
Beyond that window, or for any retrieval further back than a live reconnect, the client calls the History API. It retrieves messages indexed by channel, timestamp, and serial number. It is worth being precise about what History is not: it is not a database, and it does not support searching by author or running relational queries across messages. It is purpose-built for one job: retrieving a channel's timeline by time range. The typical pattern is to subscribe to the live channel first, then fetch everything published before that point, so there is no gap between historical and realtime messages.
Message size restrictions - and how they compound the other gaps
Pusher enforces a hard 10KB limit per message, and exceeding it silently drops the message with no error returned to the publisher. Pusher's own guidance for larger payloads is custom chunking on both the publisher and the subscriber side.
This is where the absence of ordering and history compounds the size limit rather than sitting alongside it as a separate problem. A developer chunking a large payload on Pusher has to split it into pieces under 10KB, then reassemble those pieces on the subscriber side in the correct order, on a platform that does not guarantee message order. The chunking problem and the ordering problem become the same problem.
Ably's default message size is 64KB - large enough to avoid chunking for most payloads. Where a response does span multiple messages, guaranteed ordering means the chunks arrive in sequence without the application needing to track that order itself. Higher limits are also available on Enterprise plans.
Ably vs Pusher on delivery guarantees: a summary
The four sections above explain how each platform behaves and why. The table below summarizes the outcome of each one.
| Dimension | Pusher | Ably |
|---|---|---|
| Message ordering | Not guaranteed — parallel backend processing means subscribers may receive messages out of sequence | Guaranteed per publisher per channel — every subscriber receives messages in the order they were published |
| Exactly-once delivery | Not guaranteed — no idempotent publishing mechanism | Yes — idempotent publishing prevents duplicate delivery |
| Message history | Cache Channels stores the most recent event per channel for up to 30 minutes (state snapshot, not replay) | 2-minute rewind on reconnect; up to 72-hour history available on higher tiers |
| Connection recovery | Messages sent while a client is disconnected are permanently lost | Automatic replay of missed messages on reconnect within a 2-minute window, with exactly-once semantics |
| Message size limit | 10KB hard limit — messages exceeding this are silently dropped | 64KB by default; higher limits available on Enterprise |
| Concurrent channel limit | 100 members per presence channel | No equivalent hard limit documented |
| Fan-out counting | Yes — one publish to N subscribers counts as N+1 messages | Yes — one publish to N subscribers counts as N+1 messages |
What this looks like in production
In practice, message ordering, exactly-once delivery, message history, and connection recovery determine what your application has to handle itself versus what the platform handles for you.
If your application can tolerate a message arriving late, out of order, or not at all without anything breaking, Pusher's gaps cost you nothing. If it can't, each gap becomes a piece of infrastructure you have to build and maintain: client-side sequence tracking to fix ordering, your own deduplication to fix exactly-once, a database and fetch-on-reconnect logic to fix history, and a chunking layer to fix the 10KB limit. None of these are exotic engineering problems, but together they add up to rebuilding, in your application code, the guarantees Ably provides at the platform level.
The clearest case is AI token streaming, where all four properties compound: out-of-order tokens corrupt the rendered response, a duplicate token duplicates visible text, a dropped connection loses everything generated so far, and a long response can hit the 10KB limit outright. Ably AI Transport exists specifically because this combination is common enough to warrant a dedicated layer, rather than four separate workarounds.
Building on guaranteed ordering, exactly-once delivery, and session recovery means these properties are available to every feature you ship - without revisiting the infrastructure layer each time. If that's the foundation you want, start building on Ably for free or talk to an engineer about your delivery requirements.
Frequently asked questions
Are messages lost if no one is subscribed to a channel when they're published?
On Pusher, yes. Its own documentation states that if there are no clients subscribed to a channel when a message is triggered, that event is instantly lost, with no buffering or replay for late subscribers. On Ably, a client that subscribes after a message was published can retrieve it via the History API, rather than depending on being subscribed at the exact moment of publish.
Is there a way to get Pusher to acknowledge that a message was delivered, even without a full delivery guarantee?
No. Pusher's trigger call confirms the message was accepted by Pusher's API, not that it reached any subscriber. There is no subscriber-side acknowledgment mechanism, so a publisher has no way to know whether a specific client actually received a specific message.
Do Pusher's reconnection issues (e.g. on React Native or iOS) affect Channels only, or also Beams?
The documented reconnection issues, including React Native backgrounding, iOS auto-reconnect failures, and network-switch failures, are specific to Channels, Pusher's pub/sub product. Beams, Pusher's separate push notification product, uses native platform push services such as APNs and FCM rather than a persistent WebSocket connection, so it is not affected by the same reconnection failure modes. However, Beams also does not provide ordering or delivery guarantees of its own.
Can I get exactly-once delivery on Pusher by building my own deduplication?
You can build a workaround, but you will be reimplementing what the platform does not provide. The typical pattern is attaching a unique ID to every published message and having the subscriber track which IDs it has already processed, discarding repeats. This works, but it shifts the engineering cost, and the risk of getting it wrong, entirely onto your application, for every client that consumes the channel.
Does the 10KB Pusher limit affect text-only messages, or only large payloads like images?
It affects any message, regardless of content type, including pure text. A detailed LLM response with code formatting, a structured JSON payload, or a long chat message can all exceed 10KB on their own. Pusher's SDK does not return an error when this happens. The message is silently dropped, which means a developer who has not load-tested with realistic payload sizes may not discover the limit until it fails in production.
Recommended Articles

Scaling AWS API Gateway WebSocket APIs - what you need to consider
AWS API Gateway WebSocket APIs allow you to power realtime communication for use cases like chat and live dashboards. But how well does AWS API Gateway scale?

Cord alternatives: Top 5 competitors to consider in 2024
A round-up of the best alternatives to Cord for adding collaborative features - from avatar stacks to component locking - in-app.
Ably vs Pusher deep dive: SSO, compliance, SLAs, and enterprise security compared
Compare Ably and Pusher on SSO, SOC 2, HIPAA, SLAs, and network security - the dimensions that matter in regulated industry procurement.