LiveObjects operations are billed as messages. This page explains how different LiveObjects operations contribute to your Ably usage.
Message counting
Each operation is sent as an ObjectMessage. Ably bills for each outbound message sent from a client, and for each inbound message delivered to each client.
When a client performs an operation (such as setting a value on a LiveMap or incrementing a LiveCounter), this generates an outbound message. When that operation is broadcast to other connected clients, each client receives an inbound message.
For example, if 5 clients are connected to a channel and one client increments a counter:
- 1 outbound message (from the client performing the increment)
- 5 inbound messages (one delivered to each of the 5 connected clients, including the client that sent it)
LiveMap operations
Removing a key and setting a primitive value always sends one message:
1
2
3
4
5
// One message
await myObject.get('settings').set('theme', 'dark');
// One message
await myObject.get('settings').remove('theme');Creating a shallow LiveMap sends two messages: one to create the new LiveMap object, and one to assign it to the target object:
1
2
3
4
// Two messages: create map + assign to 'settings'
await myObject.set('settings', LiveMap.create({
shallow: 'data'
}));Nested LiveMap or LiveCounter objects each generate their own creation messages:
1
2
3
4
5
6
7
8
9
10
// Four messages:
// - create visits counter
// - create stats map
// - create settings map
// - assign to 'settings'
await myObject.set('settings', LiveMap.create({
stats: LiveMap.create({
visits: LiveCounter.create()
})
}));Batch operations result in a message for each operation included in the batch:
1
2
3
4
5
6
7
// Four messages
await myObject.get('settings').batch((ctx) => {
ctx.set('theme', 'dark');
ctx.set('fontSize', 14);
ctx.set('notifications', true);
ctx.remove('oldSetting');
});LiveCounter operations
Incrementing and decrementing a counter always sends one message:
1
2
3
4
5
// One message
await myObject.get('visits').increment(5);
// One message
await myObject.get('visits').decrement(3);Creating a LiveCounter sends two messages: one to create the new LiveCounter object, and one to assign it to the target object:
1
2
// Two messages: create counter + assign to 'visits'
await myObject.set('visits', LiveCounter.create(0));Creating a counter nested within a LiveMap also generates messages for the parent map:
1
2
3
4
5
6
7
8
9
10
// Four messages:
// - create visits counter
// - create stats map
// - create settings map
// - assign to 'settings'
await myObject.set('settings', LiveMap.create({
stats: LiveMap.create({
visits: LiveCounter.create(0)
})
}));Batch operations result in a message for each operation included in the batch:
1
2
3
4
5
6
// Three messages
await myObject.get('visits').batch((ctx) => {
ctx.increment(5);
ctx.increment(3);
ctx.decrement(2);
});Synchronization
During initial synchronization and resynchronization, each object on the channel is sent as a message.
For example, if a channel contains 10 objects (such as LiveMap and LiveCounter instances), a client attaching to the channel will receive 10 messages during synchronization.
Similarly, if a client becomes disconnected and needs to resynchronize, it will receive 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.
Subscriptions
Subscribing to updates does not affect the number of messages received by a client. Any client attached to a channel with the object-subscribe capability automatically receives all object messages for that channel. Subscribing to updates on an object adds a listener that is called whenever the client receives updates for that object.
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).