Should I use the REST or Realtime library?

The REST library is stateless. It is a wrapper around our REST API, however it provides a lot of additional functionality including  authentication, routing around network partitions or data center availability issues, encryption and binary encoding. (Why you should use the REST library instead of the REST API directly). The Realtime library is stateful; it establishes a connection to Ably for that client and maintains state for the life of the connection.


The REST library is almost exclusively used serverside. The Realtime library can be used both serverside and clientside.


Additionally, we support a number of queueing protocols including AMQP and STOMP, which are well suited to consuming realtime data from worker servers.


Reasons to use the REST library

See the REST library documentation

  • Your application server is used to primarily issues tokens for clients and/or publish messages on channels.
  • Your application is mostly stateless i.e. you process a request or respond to an event, and then move onto the next request or event without any previous state carrying through.
  • Your prefer a synchronous request over an asynchronous request.  Note not all REST libraries are synchronous, but where the platform offers a synchronous and asynchronous approach, the REST libraries are more often synchronous.
Reasons to use the Realtime client library

See the Realtime library documentation

  • You are developing a mobile or web client that needs to subscribe to messages in real time.
  • Your application needs to register its presence on a channel, or listen for others becoming present in real time.
  • You want to maintain a persistent connection to Ably, attach to one or more channels, and publish and subscribe to messages.
  • You want to publish messages at a very high volume, which is much more efficient over a realtime connection, as publishes are pipelined over a websocket.
  • You need to publish messages with very low latency: Realtime publishes have much lower overhead than REST publishes, so have significantly lower latency.
  • You're running into your hourly API request limits. REST publishes use a separate API request per publish, so if you're hitting your limits there, this may be a reason to use the Realtime library.


Reasons to use our Reactor Queues (AMQP & STOMP protocols)

See the Reactor Queues documentation

  • You have one or more worker servers that want to consume realtime data published into the Ably system as-it-happens. However instead of all of your servers receiving all of the data (which is how channel pub/sub works), each message is delivered to only one of the consumers (your servers).  This ensures that as the volumes of data increase, you can simply scale up the number of servers you need i.e. if each server can process X messages, and the number of servers you have is Y, then the collective capacity of your servers is X multiplied by Y.  Using a realtime channel with pub/sub, this is not the case as each server receives all of the messages.
  • You want Ably to act as a buffer to your servers so that if your servers are unavailable, or cannot process messages quickly enough, Ably will build up a backlog of messages to be consume when your servers are able to process them.
  • You can use any AMQP or STOMP compatible client library, it is unnecessary to use an Ably client library.


Other protocols


Other considerations


In some situations, either library can be used, and the decision will come down to efficiency.


Getting presence

For example, if your server needs an up-to-date copy of the presence set (using channel.presence.get() ) of some channel very regularly, then the realtime library will be able to do this more efficiently. This is because it keeps a local copy of the presence set and is notified over the realtime connection whenever that changes, so it can satisfy a request for the presence set immediately from its local copy. Wheras the REST library has to request the presence set from Ably with an http request every time channel.presence.get() is called. On the other hand, if you are doing this with a large number of high-member-count channels and don't need to access the presence set of each one very often, using the realtime library will subject the server to a lot of traffic; in that situation the REST library may be more appropriate, even with the additional latency. It's a judgement you need to make based on your usage pattern.


(Also be aware that the choice will impact your package quotas and limits. If using the realtime library, messages (including presence changes) sent to a channel your server is attached to counts against your package quota, but calling presence.get() on an already-attached channel will be free (as it's satisfiable locally). If using the realtime library, every call will result an API request, which are rate-limited, and a presence.get() request will count every member returned as a message against your quota. So repeatedly calling presence.get() on a high-member-count channel with the REST library can use up your package quota more quickly; in such situations using the realtime library will make more efficient use of your package).


Publish patterns

If you are using a realtime client anyway, there are very few reasons to not publish over it. You can publish to a channel without attaching to it (and you shouldn't attach unless you want to subscribe to the channel or enter presence on it); there is a limit on the number of channels you can be attached to, but just publishing avoids that limit. If you are already connected to Ably with a realtime client, the publish will be faster and more efficient than a REST publish: using the existing websocket avoids needing a TLS handshake, your auth credentials don't need to be rechecked, and so on.

Note that by default, the acknowledgements for realtime publishes (which trigger the publish callback / promise to resolve) can be 'rolled up' by the server for up to 500ms, to do multiple acks at once. If you need an acknowledgement quickly, you can specify `transportParams: {ackRollup: "0"}` in the client options (that's for ably-js; the syntax for specifying transport params in other client libs may differ).

There are two scenarios where you may want to use a rest client to publish instead of a realtime client (where you have the choice):

1. Scenarios where you don't want to maintain a websocket connection to Ably. You just want to do a one-off publish, and not have a persistent connected client. For example, in an AWS Lambda function, or a Rails request handler. There is no point instantiating a realtime client, waiting for it to connect, doing one publish, then closing the connection again; that's strictly worse than a rest publish.

2. Scenarios where the 50 message per second rate limit for a realtime connection would be an issue. For example, if you want to publish 500 messages to 500 different channels at once. Over a realtime connection, if you tried to do all of those at once the rate limits would prevent you, you would need to stagger them, and it would take 10s in total. If firing off 500 rest requests, they can all happen in parallel. (Though beware that some REST client libraries have not yet been upgraded to use http2, and use fixed-size tcp socket pools that serialize publishes through those). Though for that use-case you may want to consider using our batch publish API, so that you can publish messages to up to 100 channels in each HTTP request.

Of course, each use-case is different; for example, if you wanted to do a steady-state publish of 100 messages per second, using a pool of a couple of realtime connections and sharding the publishes between them may be the best choice.

(Older versions of client libraries needed to be attached to channels before they could publish, and a publish to a non-attached channel would implicitly attach. This meant that the realtime vs rest question had a very different answer. But this is no longer the case for recent versions of any of our realtime client libraries. Make sure you're on the latest version of the Ably SDK.)