An Ably alternative: what to look at and when to stay
6 min readThe Eventeer team
Ably is a realtime messaging platform built around the publish/subscribe pattern. You create named channels, clients subscribe and publish to them, and Ably adds features on top: presence (who is on a channel), channel history, and client libraries. It is aimed at apps where many clients talk to each other: chat, multiplayer and similar features.
Last reviewed: November 2026. People look for an alternative for fit reasons, not because Ably is weak. Some only need one direction, server to browser. Some want to run the server themselves. Some are really moving events from devices and third-party services, and a general pub/sub product is more than that job needs. This post lists the questions that decide it and four options, including ours, with honest notes on each.
What to look for in an Ably alternative
Answer these first. They remove most of the list.
- Who publishes? If browsers and apps publish to each other, you need a pub/sub product. If only your servers, devices and webhooks produce events and clients just watch, a simpler stream is enough.
- Do you need presence? Knowing which users are currently on a channel is a specific feature. Not every service has it.
- Do you need client libraries? Or is a plain WebSocket in the browser fine?
- What happens on reconnect? Can a client catch up on what it missed, and how far back?
- Hosted or self-hosted? Running the server yourself gives control and costs operations time.
- Where do events come from? Webhooks, IoT devices and external feeds are a different input from client publishes.
The alternatives
Eventeer
Eventeer is a hosted event hub, not a general pub/sub product. Events come in through webhook listeners, device WebSocket connections, or a WebSocket source Eventeer opens to an external URL. They are stored for your plan’s retention period. They go out to clients over a stream WebSocket, or to your servers as signed outbound webhooks.
What overlaps with Ably:
- Streams to clients. A client opens
GET /out/s/<stream_key>as a WebSocket and receives each event as a JSON frame, with an optional filter on the stream. - Replay. Pass
since=<last event id>and the server sends stored events first (up to 1,000 per connection, then areplay_truncatedmarker), then alivemarker, then live events. Replay is at-least-once, so clients dedupe by eventid. - Device connections. Devices keep a WebSocket open, get a per-event ack, show online status and last seen, and can receive messages pushed down from the API.
- Storage. Every event is stored and can be browsed and filtered.
What it does not do: there is no presence for end users, and no client-to-client publishing (clients on a stream receive, they do not publish to it). There is no client SDK: clients use the browser’s plain WebSocket. Live frames are at-most-once, so reconnect with since to recover anything missed. If your app needs chat-style two-way channels, Eventeer is the wrong tool.
const ws = new WebSocket(`wss://app.eventeer.io/out/s/${key}?token=${token}&since=${lastId}`)
ws.onmessage = (m) => { const f = JSON.parse(m.data); if (f.type === "event") lastId = f.id }
It fits when producers are devices, webhooks and your backend, and the browser only needs to watch. See realtime streams and, for a closest-match comparison of a realtime service, Eventeer vs Pusher.
Pusher Channels
Pusher Channels is the nearest hosted alternative in shape. Its documentation describes a publish/subscribe model with named channels, public and private channels, and presence channels that show who is online. It lists client libraries for browsers, iOS and Android, PHP frameworks, cloud functions, bash scripts and IoT devices, and it can send realtime activity to your system through webhooks. It fits when you want a hosted pub/sub product of the same kind.
Centrifugo
Centrifugo is an open-source realtime messaging server that you host yourself. Its documentation presents it as a self-hosted alternative to Pusher, Ably and PubNub. Clients can connect over WebSocket, HTTP streaming, Server-Sent Events, WebTransport or gRPC. It documents online presence, channel history with automatic recovery on reconnect, and official browser and mobile SDKs. It fits when you want control of the infrastructure and are happy to operate it.
Socket.IO
Socket.IO is a library, not a service. Its documentation describes low-latency, bidirectional, event-based communication that uses WebSocket, HTTP long-polling or WebTransport, with automatic reconnection, rooms, acknowledgements and client implementations in many languages. You run the server inside your own application. It fits when you want full control inside your own application code.
Comparison
| Capability | Ably | Eventeer | Pusher Channels | Centrifugo | Socket.IO |
|---|---|---|---|---|---|
| Client libraries | Yes | No, plain WebSocket | Yes | Yes | Yes |
| Presence | Yes | No | Yes | Yes | Not documented |
| Catch-up after reconnect | Yes, short-term history | Yes, since replay from stored events |
Not documented | Yes, history with recovery | Partly (connection state recovery, not always successful) |
| Clients publish | Yes | No | Yes, client events | Partly (opt-in) | Yes |
| Receives webhooks and device sockets as input | Not documented | Yes | Not documented | Not documented | Not documented |
| You operate the server | No, hosted | No, hosted | Not documented | Yes | Yes |
“Not documented” means the pages reviewed for this post did not say, not that the feature is missing.
When to stay with Ably
Stay if your clients publish to each other, if you need presence, or if you want client libraries. Ably documents all three, with history for catching up after short disconnections. It describes history as meant for that, not as a primary database, which is a fair design. A stream-only product will feel limiting the moment a feature needs a user to send something to other users.
Also stay if nothing is wrong. Moving a working realtime layer has a cost, and “different” is not a reason.
Moving to Eventeer
This only makes sense if your clients mostly watch. The steps, from the API reference:
- Create a listener with
POST /api/v1/listeners(name,type,auth_mode) and a stream withPOST /api/v1/streams(name,auth_mode,listener_ids, optionalfilter), using an organization API key (Authorization: Bearer evk_...). - Issue credentials with
POST /api/v1/streams/:key/credentialsfor browsers, andPOST /api/v1/listeners/:key/credentialsfor producers (a listener token, an HMAC secret or a device token). The plaintext secret is returned once. - Point your producers at the listener:
POST /in/w/<listener_key>for webhooks, or a device WebSocket at/in/d/<listener_key>. From your backend you can also ingest withPOST /api/v1/listeners/:key/events. - Replace the Ably subscribe call in the client with a
WebSocketto/out/s/<stream_key>. Keep the last eventidand reconnect withsince. - Dedupe on
id, since replay is at-least-once. - Move anything that needed presence or client publishing elsewhere, or keep Ably for it.
Sources
Every statement about Ably, Pusher Channels, Centrifugo and Socket.IO in this post comes from these pages, last reviewed November 2026.
- Ably: Channels (channels, pub/sub, history, presence, client libraries)
- Ably: Pub/Sub platform overview
- Ably: Presence (presence members and events)
- Ably: History (history for catching up, not a primary database)
- Pusher Channels documentation (pub/sub, presence channels, client libraries, webhooks)
- Pusher Channels: events and client events (client events)
- Centrifugo introduction (open source, self-hosted, transports, presence, history, SDKs)
- Socket.IO documentation (transports, reconnection, acknowledgements, clients)
- Socket.IO rooms
- Socket.IO connection state recovery
- Centrifugo channels (client publishing is opt-in)