First, have a read through How does Ably count messages, to make sure you understand how messages are charged.


Consider using the Statistics API to get a detailed breakdown of exactly what's using up messages in your package (by messages sent over REST and realtime, messages received over REST (i.e. history) and realtime, presence messages, reactor messages, and so on), by minute, hour, day, or month. This will tell you what area you need to focus on.


If outbound realtime messages dominate, make sure you're not sending lots of messages that clients don't want. A client attached to a channel then it will receive all messages on it, so if (for example) you have many clients which only need to publish on a channel and not subscribe, you can use capabilities to stop them from being sent messages (by having them connect with a key or token without the 'subscribe' capability).


If clients don't need to be sent their own messages, they can set the echoMessages client option to false.


Remember that client-side filtering of messages has no effect on message counting — the channel is the smallest unit of distribution, all messages published on a channel are received by every client attached to it (unless those clients don't have 'subscribe' capabilities; see above). See the realtime subscribing to messages documentation.


If you are using presence, bear in mind that the average number of messages used goes approximately as the square of the number of clients attached to the channel, since each client sends its activity state changes to every other client on the channel; so this can sometimes result in unexpectedly large package usage. See Why do you have a limit on the number of members present on a channel? for more information.


If you are using history, remember that every message stored counts as one message. You can enabled or disable persistence on a per-namespace basis, so it's worth disabling it on namespaces you're not using history with. Every message retrieved also counts as one message, so if you only need (for example) the most recent 5 messages, use the limit param to control how many messages you get in your history query, so you don't pay for messages you're just going to discard.


If using Reactor rules, remember every message sent to a queue etc. counts as one message, so if you're not using some rule, disable it from the dashboard.