# Billing
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`](https://ably.com/docs/liveobjects/concepts/operations#properties). 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:
```javascript
// 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:
```javascript
// 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:
```javascript
// 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:
```javascript
// 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:
```javascript
// 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:
```javascript
// 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:
```javascript
// 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:
```javascript
// 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](https://ably.com/docs/liveobjects/concepts/objects#reachability) objects are counted. Ably may send [tombstone](https://ably.com/docs/liveobjects/concepts/objects#tombstones) 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](https://ably.com/docs/liveobjects/rest-api-usage) also counts messages for operations performed.
When fetching objects via the REST API, each instance of an [object type](https://ably.com/docs/liveobjects/concepts/objects#object-types) 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).