> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ably/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Occupancy

Occupancy provides high level metrics about the clients attached to a channel. This includes the number of [connections](/docs/connect) currently attached to a channel, and the number of connections attached that are permitted to publish and subscribe to the channel.

## Occupancy metrics

The following are the metric categories that occupancy reports:

| Metric                  | Description                                                                              |
| ----------------------- | ---------------------------------------------------------------------------------------- |
| **connections**         | The number of connections                                                                |
| **publishers**          | The number of connections that are authorized to publish                                 |
| **subscribers**         | The number of connections that are authorized to subscribe to messages                   |
| **presenceSubscribers** | The number of connections that are authorized to subscribe to presence messages          |
| **presenceConnections** | The number of connections that are authorized to enter members into the presence channel |
| **presenceMembers**     | The number of members currently entered into the presence channel                        |

## Realtime occupancy updates

Subscribe to occupancy events in realtime using the [`occupancy` channel option](/docs/channels/options#occupancy):

<Code>
  ```javascript theme={null}
  const channel = realtime.channels.get('my-channel', {
    params: { occupancy: 'metrics' }
  });

  await channel.subscribe('[meta]occupancy', (message) => {
    const metrics = message.data.metrics;
    console.log('Connections:', metrics.connections);
    console.log('Publishers:', metrics.publishers);
    console.log('Subscribers:', metrics.subscribers);
  });
  ```

  ```python theme={null}
  channel = realtime.channels.get(
      'my-channel',
      channel_options={'params': {'occupancy': 'metrics'}}
  )

  def occupancy_listener(message):
      metrics = message.data['metrics']
      print('Connections:', metrics['connections'])
      print('Publishers:', metrics['publishers'])
      print('Subscribers:', metrics['subscribers'])

  await channel.subscribe('[meta]occupancy', occupancy_listener)
  ```

  ```java theme={null}
  Map<String, String> params = new HashMap<>();
  params.put("occupancy", "metrics");
  ChannelOptions options = new ChannelOptions();
  options.params = params;

  Channel channel = realtime.channels.get("my-channel", options);

  channel.subscribe("[meta]occupancy", new MessageListener() {
      @Override
      public void onMessage(Message message) {
          // Access occupancy metrics from message.data
      }
  });
  ```
</Code>

## Query occupancy via REST

You can query occupancy for a single channel using the REST API:

<Code>
  ```javascript theme={null}
  const rest = new Ably.Rest('{{API_KEY}}');
  const channel = rest.channels.get('my-channel');

  const channelDetails = await rest.request(
    'GET',
    `/channels/${channel.name}`,
    2,
    null,
    { occupancy: 'metrics' },
    null
  );

  const metrics = channelDetails.items[0].status.occupancy.metrics;
  console.log('Connections:', metrics.connections);
  console.log('Publishers:', metrics.publishers);
  ```

  ```python theme={null}
  rest = AblyRest('{{API_KEY}}')
  channel = rest.channels.get('my-channel')

  channel_details = await rest.request(
      'GET',
      f'/channels/{channel.name}',
      version=2,
      params={'occupancy': 'metrics'}
  )

  metrics = channel_details.items[0]['status']['occupancy']['metrics']
  print('Connections:', metrics['connections'])
  print('Publishers:', metrics['publishers'])
  ```
</Code>

## Enumerate channels with occupancy

List all active channels and their occupancy:

<Code>
  ```javascript theme={null}
  const rest = new Ably.Rest('{{API_KEY}}');

  const result = await rest.request(
    'GET',
    '/channels',
    2,
    null,
    { occupancy: 'metrics' },
    null
  );

  result.items.forEach((channel) => {
    console.log(`Channel: ${channel.name}`);
    console.log('Connections:', channel.status.occupancy.metrics.connections);
  });
  ```
</Code>

## Occupancy payload structure

When subscribing to `[meta]occupancy` events, the message structure is:

<Code>
  ```json theme={null}
  {
    "name": "[meta]occupancy",
    "data": {
      "metrics": {
        "connections": 5,
        "publishers": 3,
        "subscribers": 5,
        "presenceConnections": 2,
        "presenceMembers": 2,
        "presenceSubscribers": 4
      }
    },
    "timestamp": 1612286351217
  }
  ```
</Code>

## Use cases

### Display active users

<Code>
  ```javascript theme={null}
  await channel.subscribe('[meta]occupancy', (message) => {
    const connections = message.data.metrics.connections;
    document.getElementById('user-count').textContent = 
      `${connections} user${connections !== 1 ? 's' : ''} online`;
  });
  ```
</Code>

### Monitor capacity

<Code>
  ```javascript theme={null}
  const MAX_CONNECTIONS = 100;

  await channel.subscribe('[meta]occupancy', (message) => {
    const connections = message.data.metrics.connections;
    const usage = (connections / MAX_CONNECTIONS) * 100;
    
    if (usage > 90) {
      console.warn(`Channel at ${usage.toFixed(1)}% capacity`);
    }
  });
  ```
</Code>

### Track engagement

<Code>
  ```javascript theme={null}
  await channel.subscribe('[meta]occupancy', (message) => {
    const metrics = message.data.metrics;
    
    analytics.track('Channel Occupancy', {
      connections: metrics.connections,
      publishers: metrics.publishers,
      subscribers: metrics.subscribers,
      timestamp: message.timestamp
    });
  });
  ```
</Code>

## Occupancy vs Presence

| Feature              | Occupancy                  | Presence                    |
| -------------------- | -------------------------- | --------------------------- |
| **Purpose**          | High-level channel metrics | Individual member tracking  |
| **Identifies users** | No                         | Yes (by clientId)           |
| **Member data**      | No                         | Yes (custom status)         |
| **Overhead**         | Minimal                    | Higher (per-member events)  |
| **Best for**         | Showing "X users online"   | Avatar stacks, member lists |

Use occupancy when you only need counts. Use [presence](/docs/pubsub/presence) when you need to know who is online.

## Next steps

* Learn about [presence](/docs/pubsub/presence) for detailed member tracking
* Explore [channel metadata](/docs/metadata-stats/metadata)
* Understand [channel options](/docs/channels/options)
