LiveObjects pricing
LiveObjects is priced on the number of unique users that interact with your application each month. Object operations, synchronization and connection time don't affect your bill.
Ably prices on monthly active users (MAUs). A user who interacts with your application counts once in a calendar month, whichever products they use, however many objects they update or synchronize, however many channels they attach to, and however long they stay connected.
Monthly active users
An MAU is a unique clientId that is active during a calendar month. LiveObjects is a plugin that loads into a realtime client, and a clientId becomes active when a realtime client created from the device package connects to Ably, whether or not it uses LiveObjects. It is counted once for that month, whether it was active for a minute or every day.
Each clientId is counted once per app. The same user counts once whether they connect from one device or several, and whether they use LiveObjects alone or LiveObjects alongside Pub/Sub, Chat, Spaces, AI Transport or LiveSync in the same app.
Identifying users
Because an MAU is identified by their clientId, the way you assign them decides what you are billed for:
- Assign one
clientIdper user, and use it on every device and in every session. A user who connects from a phone and a laptop with differentclientIds counts as two MAUs. - Never share a
clientIdbetween users.
Anonymous users
Users who are anonymous to your application still require a clientId. Generate an identifier for each anonymous user and store it on their device, so that a returning anonymous user counts only once. If your application generates a fresh identifier on every visit, each visit counts as a new MAU.
Servers
Realtime clients created from the server package are not counted as MAUs, however many objects they update, and nor are calls to the LiveObjects REST API from your servers through the server package.
If you call the REST API directly rather than through an SDK, declare the caller as a server. With API key authentication, add clientType=server as a request or connection parameter. With token authentication, add the x-ably-clientType claim with the value server to the JWT you issue to the server. A request that doesn't declare itself as a server is counted as a user.
Resource-based pricing
If your account is still on resource-based pricing, LiveObjects is charged on what you use rather than on your number of MAUs: per million messages, per million channel minutes and per million connection minutes. LiveObjects operations are ObjectMessages. Each state mutation, such as setting a key, incrementing a counter or creating an object, generates one or more ObjectMessages, and each follows the standard inbound and outbound counting pattern. How messages are counted lists them.
To move your account to MAU pricing, follow the migration guide.
Synchronization
During initial synchronization and resynchronization, Ably sends each object on the channel as a message.
For example, if a channel contains 10 objects (such as LiveMap and LiveCounter instances), a client attaching to the channel receives 10 messages during synchronization.
Similarly, if a client becomes disconnected and needs to resynchronize, it receives messages for each object that needs to be synchronized.
Only reachable objects are counted. Ably may send tombstone objects to the client, but these will not count towards your usage.
REST API
The LiveObjects REST API also counts messages for operations performed.
When fetching objects via the REST API, each instance of an object type included in the response is counted as one message.
Each operation published via the REST API counts as one message. When creating objects using the path field, the server constructs two messages (a create operation and a MAP_SET operation to assign it).
Resource efficiency
Regardless of whether you are on MAU pricing or resource-based pricing, effectively managing resources is beneficial to your application:
- Prefer flat data structures. Setting a primitive value on a LiveMap is one message, while creating a nested LiveMap is two or more (one to create the object, one to assign it), plus more for each level of nesting.
- Minimize objects per channel. Each object on a channel is synchronized when a client attaches or resynchronizes, so distribute objects across channels based on which clients need access to them.
- Detach from channels and close connections when they are no longer needed to tidy up resources.