# Message counting Messages are the primary unit of consumption that Ably charges for. Understanding which operations count as messages helps you estimate and manage costs. ## How Ably counts messages As a general rule, most operations involve publishing and receiving messages. Each operation generates: * 1 inbound message when a client publishes or performs an operation * 1 outbound message for each subscriber that receives it For example, if 1 client publishes a message to a channel with 10 subscribers, this counts as **11 messages** (1 inbound + 10 outbound). By default, [echo messages](https://ably.com/docs/pub-sub/advanced.md#echo) are enabled, which means the publisher also receives its own message as an outbound delivery. In the example above, echo adds 1 outbound message for a total of **12 messages**. Client-side [message filtering](https://ably.com/docs/api/realtime-sdk/channels.md#subscribe), where a subscribe callback selectively processes messages, does not reduce your message count. Ably delivers all messages on a channel to every subscriber regardless of client-side filtering. To filter messages server-side and reduce outbound message counts, use [subscription filters](https://ably.com/docs/pub-sub/advanced.md#subscription-filters). The tables below list all operations that count as messages. Unless noted otherwise, each operation follows this inbound/outbound pattern. `Time` and `Ping` operations are not counted. ## Message size Ably calculates message size as the sum of the `name`, `clientId`, `data`, and `extras` [properties](https://ably.com/docs/api/realtime-sdk/messages.md#properties) before any compression or expansion occurs in the serialization process. This applies to all products built on Pub/Sub, including Chat. * `name` and `clientId` are calculated as the size in bytes of their UTF-8 representation. * `data` is calculated as the size in bytes if it is binary, or its UTF-8 byte length if it is a string. * `extras` is calculated as the string length of its JSON representation. Ably bills messages in 5KiB chunks. A message up to 5KiB counts as 1 message. A 50KiB message counts as 10 messages, and a 16KiB message counts as 4 messages. Each package has a bandwidth allowance based on an average message size of 5KiB. If your total bandwidth for the month exceeds this baseline, Ably charges overage per GiB. See [maximum message size](https://ably.com/docs/platform/pricing/limits.md#message) for the size limits per package type. ## Pub/Sub operations The following table shows how [Pub/Sub](https://ably.com/docs/pub-sub.md) operations contribute to your message count: | Operation | Messages counted | | --- | --- | | [Messages](https://ably.com/docs/channels/messages.md) || | Publish | 1 inbound message | | Message delivery | 1 outbound message per subscriber | | [Presence](https://ably.com/docs/presence-occupancy/presence.md) || | Presence enter | 1 inbound message | | Presence leave | 1 inbound message | | Presence update | 1 inbound message | | Presence event delivery | 1 outbound message per presence subscriber | | Presence REST query | 1 outbound message per member returned | | Batch presence request | 1 outbound message per member across all queried channels | | [Storage and history](https://ably.com/docs/storage-history/storage.md) || | Persistence storage | 1 additional message per stored message | | History retrieval | 1 outbound message per retrieved message | | [Rewind](https://ably.com/docs/channels/options/rewind.md) on attach | 1 outbound message per rewound message (up to 100) | | [Integrations](https://ably.com/docs/platform/integrations.md) || | Integration delivery | 1 outbound message per integration target | | [Inbound integration publish](https://ably.com/docs/platform/integrations.md#inbound) | 1 inbound message | | [Push notifications](https://ably.com/docs/push.md) || | Push notification delivery | 1 outbound message per delivered notification | | [Annotations](https://ably.com/docs/messages/annotations.md) || | Annotation publish | 1 inbound message | | Annotation delete | 1 inbound message | | [Annotation summary delivery](https://ably.com/docs/messages/annotations.md#annotation-summaries) | 1 outbound message per subscriber; multiple annotations may be rolled up into a single summary | | [Metadata and stats](https://ably.com/docs/metadata-stats/metadata.md) || | Lifecycle event (`[meta]connection.lifecycle`, `[meta]channel.lifecycle`) | 1 outbound message per event | | `[meta]stats:minute` event | 1 outbound message per event | | `[meta]log` subscription | Not counted | For Pub/Sub-specific cost optimization strategies, see [Pub/Sub pricing](https://ably.com/docs/pub-sub/pricing.md). ## Chat operations The [Chat SDK](https://ably.com/docs/chat.md) is built on top of [Pub/Sub](https://ably.com/docs/pub-sub.md). All Chat operations generate Pub/Sub messages that follow the same counting rules. | Operation | Messages counted | | --- | --- | | [Messages](https://ably.com/docs/chat/rooms/messages.md) || | Send message | 1 inbound message | | Message delivery | 1 outbound message per subscriber | | Update message | 1 inbound message | | Message update delivery | 1 outbound message per subscriber | | Delete message | 1 inbound message | | Message deletion delivery | 1 outbound message per subscriber | | [History](https://ably.com/docs/chat/rooms/history.md) || | History retrieval | 1 outbound message per retrieved message | | [Typing indicators](https://ably.com/docs/chat/rooms/typing.md) || | Typing keystroke | 1 inbound message; repeats every heartbeat interval (default 10s) | | Typing keystroke delivery | 1 outbound message per subscriber per heartbeat | | Typing stop | 1 inbound message | | Typing stop delivery | 1 outbound message per subscriber | | [Room reactions](https://ably.com/docs/chat/rooms/reactions.md) || | Room reaction | 1 inbound message | | Room reaction delivery | 1 outbound message per subscriber | | [Message reactions](https://ably.com/docs/chat/rooms/message-reactions.md) || | Message reaction send | 1 inbound message | | Message reaction delete | 1 inbound message | | Message reaction summary delivery | 1 outbound message per subscriber; multiple reactions may be rolled up into a single summary | | [Presence](https://ably.com/docs/chat/rooms/presence.md) || | Presence enter | 1 inbound message | | Presence leave | 1 inbound message | | Presence update | 1 inbound message | | Presence event delivery | 1 outbound message per presence subscriber | | [Occupancy](https://ably.com/docs/chat/rooms/occupancy.md) || | Occupancy event | 1 outbound message per subscriber (generated on membership changes, debounced up to 15s) | | [Moderation](https://ably.com/docs/chat/moderation.md) || | Moderation rule invocation (before or after publish) | 1 outbound webhook event per moderated message | For Chat-specific cost optimization strategies, see [Chat pricing](https://ably.com/docs/chat/pricing.md). ## LiveObjects operations [LiveObjects](https://ably.com/docs/liveobjects.md) operations are billed using ObjectMessages. Each ObjectMessage follows the standard inbound/outbound counting pattern. | Operation | Messages counted | | --- | --- | | [LiveMap](https://ably.com/docs/liveobjects/map.md) || | LiveMap set or remove | 1 inbound message per operation | | LiveMap create (shallow) | 2 inbound messages (create + assign) | | [LiveCounter](https://ably.com/docs/liveobjects/counter.md) || | LiveCounter increment or decrement | 1 inbound message | | LiveCounter create | 2 inbound messages (create + assign) | | ObjectMessage delivery | 1 outbound message per connected client | | [Synchronization](https://ably.com/docs/liveobjects/pricing.md#synchronization) | 1 outbound message per object synchronized | | [REST API](https://ably.com/docs/liveobjects/pricing.md#rest-api) fetch | 1 outbound message per object in response | | [Batch](https://ably.com/docs/liveobjects/batch.md) operation | 1 inbound message per operation in the batch | Nested object creation generates additional messages for each nested object. For LiveObjects-specific cost optimization strategies, see [LiveObjects pricing](https://ably.com/docs/liveobjects/pricing.md). ## Spaces operations The [Spaces SDK](https://ably.com/docs/spaces.md) is built on top of [Pub/Sub](https://ably.com/docs/pub-sub.md) channels and [presence](https://ably.com/docs/presence-occupancy/presence.md). All Spaces operations generate Pub/Sub messages that follow the same counting rules. | Operation | Messages counted | | --- | --- | | [Members](https://ably.com/docs/spaces/space.md) || | Enter space | 1 inbound message | | Leave space | 1 inbound message | | Update profile | 1 inbound message | | Space event delivery | 1 outbound message per subscriber | | [Locations](https://ably.com/docs/spaces/locations.md) || | Set location | 1 inbound message | | Location event delivery | 1 outbound message per subscriber | | [Cursors](https://ably.com/docs/spaces/cursors.md) || | Set cursor position | 1 inbound message per batch (default batch interval 25ms) | | Cursor event delivery | 1 outbound message per subscriber | | [Locking](https://ably.com/docs/spaces/locking.md) || | Acquire lock | 1 inbound message | | Release lock | 1 inbound message | | Lock event delivery | 1 outbound message per subscriber | Live cursors use a [separate channel](https://ably.com/docs/spaces/cursors.md#foundations) from other space features due to their high update frequency. Registering multiple subscription listeners for the same event does not increase your message count, as these are [client-side filtered events](https://ably.com/docs/spaces/space.md#subscribe). For Spaces-specific cost optimization strategies, see [Spaces pricing](https://ably.com/docs/spaces/pricing.md). ## LiveSync operations [LiveSync](https://ably.com/docs/livesync.md) publishes database changes as Pub/Sub messages. Each update follows the standard inbound/outbound counting pattern. | Operation | Messages counted | | --- | --- | | Database update publish | 1 inbound message | | Update delivery | 1 outbound message per subscriber | For example, if the database connector publishes 1 update and 3 clients are subscribed, this counts as **4 messages** (1 inbound + 3 outbound). For LiveSync-specific cost optimization strategies, see [LiveSync pricing](https://ably.com/docs/livesync/pricing.md). ## Related Topics - [Overview](https://ably.com/docs/platform/pricing.md): Understand the pricing models available to you, and understand the benefits of each package type. - [Billing](https://ably.com/docs/platform/pricing/billing.md): Understand how invoicing and billing works for Ably packages. - [Limits](https://ably.com/docs/platform/pricing/limits.md): The limits associated with each Ably package. - [Pricing FAQs](https://ably.com/docs/platform/pricing/faqs.md): A list of the most commonly asked questions related to Ably pricing. ## Documentation Index To discover additional Ably documentation: 1. Fetch [llms.txt](https://ably.com/llms.txt) for the canonical list of available pages. 2. Identify relevant URLs from that index. 3. Fetch target pages as needed. Avoid using assumed or outdated documentation paths.