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.

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

If you want realtime messages or presence events to trigger execution of code on your servers or in a server-less environment (such as AWS Lambda), then you should consider Reactor WebHooks and Reactor Functions.

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

With the exception of recent versions of ably-js (see below), the realtime client needs to be attached to a channel before it publishes. (A publish to a non-attached channel will implicitly attach). This means that the first publish to a channel will be fairly high latency, and subsequent ones will be low-latency. It will also mean that once published, the client will be attached to the channel until it's explicitly detached, and will receive all messages published on that channel.

This can be inefficient and bandwidth-heavy if you are using a client to publish messages to a large number of different channels, but don't wish to receive messages on them. For that sort of use-case, you will probably want to use the rest client. However, note that publishing with the REST client is much higher-latency than publishing with the realtime client (on a channel that the realtime client is already attached to).

Very broadly, if publishing lots of messages to a few channels, you'll probably want to go for the realtime client; if publishing messages to many different channels, but not many to each one, you probably want the rest client.

With the latest version of our javascript library, you can use a realtime client and publish to a channel without attaching to it -- that is, calling channel.publish() will not implicitly attach to the channel. If you have a high publish volume, this can give you the best of both worlds.