---
source_url: https://www.pubnub.com/docs/presence/get-online-users-in-channel
title: Get online users in a channel
updated_at: 2026-10-01T14:47:31.000Z
---

# Get online users in a channel

> For AI agents: documentation index at https://www.pubnub.com/llms-full.txt

This guide shows you how to call `Here Now` to find out who is currently subscribed to a [channel](https://www.pubnub.com/docs/architecture/core-concepts.md#channel). A response gives you the total occupancy, each subscriber's [User ID](https://www.pubnub.com/docs/architecture/core-concepts.md#user-id), and, if set, their [presence state](https://www.pubnub.com/docs/presence/set-and-get-presence-state.md). Presence must be enabled on the keyset, and new keysets have it enabled by default.

* Fetch the occupant list and state for one or more channels.
* Fetch only the occupancy count, without the member list.
* Query a channel group instead of a fixed list of channels.
* Page past the per-call occupant limit.

If [Presence Management](https://www.pubnub.com/docs/presence/overview.md) restricts tracking to selected channels only, the channel you query with `Here Now` must be one of them. When [Access Manager](https://www.pubnub.com/docs/security/access-control/overview.md) is enabled, calling `Here Now` requires `read` permission on the queried channel.

## Get the occupant list and state

Call `Here Now` and set `includeState` (named `include_state` in some SDKs) to fetch each occupant's User ID and presence state alongside the channel's occupancy.

### JavaScript

```javascript
try {
  const response = await pubnub.hereNow({
    channels: ['my_channel'],
    includeState: true,
  });
  console.log('hereNow response:', response);
} catch (error) {
  console.error(`hereNow failed with error: ${error}`);
}
```

### Python

```python
here_now = pubnub.here_now() \
    .channels(["chats.room1", "chats.room2"]) \
    .include_state(True) \
    .sync()

for channel_data in here_now.result.channels:
    print("---")
    print(f"Channel: {channel_data.channel_name}")
    print(f"Occupancy: {channel_data.occupancy}")

    for occupant in channel_data.occupants:
        print(f"UUID: {occupant.uuid}, State: {occupant.state}")
```

### Java

```java
pubNub.hereNow()
        .channels(Arrays.asList("my_channel")) // who is present on those channels?
        .includeState(true) // include state with request (false by default)
        .includeUUIDs(true) // if false, only shows occupancy count
        .async(result -> {
            result.onSuccess((PNHereNowResult res) -> {
                // Iterate through channels if the request was successful
                for (PNHereNowChannelData channelData : res.getChannels().values()) {
                    System.out.println("Channel: " + channelData.getChannelName());
                    System.out.println("Occupancy: " + channelData.getOccupancy());
                    System.out.println("Occupants:");
                    for (PNHereNowOccupantData occupant : channelData.getOccupants()) {
                        System.out.println("UUID: " + occupant.getUuid() + " State: " + occupant.getState());
                    }
                }
            }).onFailure((PubNubException exception) -> {
                // Handle errors if the request fails
                System.err.println("Error retrieving hereNow data: " + exception.getMessage());
                exception.getPubnubError();
                exception.getCause();
                exception.getStatusCode();
            });
        });
```

### Kotlin

```kotlin
pubnub.hereNow(
    channels = listOf("ch1", "ch2"),
    includeState = true
).async { result: Result<PNHereNowResult> ->
    result.onSuccess { res: PNHereNowResult ->
        res.channels.values.forEach { channelData ->
            channelData.channelName // ch1
            channelData.occupancy // 3
            channelData.occupants.forEach { o ->
                o.uuid // some_uuid, returned by default
                o.state // {"data":{"isTyping":true}}, requested
            }
        }
    }.onFailure { e ->
        // handle error
        e.message
        e.statusCode
        e.pubnubError
    }
}
```

### C#

```csharp
using PubnubApi;

// Configuration
PNConfiguration pnConfiguration = new PNConfiguration(new UserId("myUniqueUserId"))
{
    SubscribeKey = "demo",
    PublishKey = "demo",
    Secure = true
};

// Initialize PubNub
Pubnub pubnub = new Pubnub(pnConfiguration);
        
PNResult<PNHereNowResult> herenowResponse = await pubnub.HereNow()
    .Channels(new string[] {
        // who is present on those channels?
        "my_channel"
    })
    .IncludeState(true) // include state with request (false by default)
    .IncludeUUIDs(true) // if false, only shows occupancy count
    .ExecuteAsync();

PNHereNowResult herenowResult = herenowResponse.Result;
PNStatus status = herenowResponse.Status;
//handle it
```

### Go

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v10"
)

// Example_hereNowWithState demonstrates getting presence with state information
func Example_hereNowWithState() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	pn := pubnub.NewPubNub(config)

	// Get presence information including user state
	_, status, err := pn.HereNow().
		Channels([]string{"my-channel"}).
		IncludeUUIDs(true). // Include list of UUIDs
		IncludeState(true). // Include state information
		Execute()

	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	if status.StatusCode == 200 {
		fmt.Println("HereNow with state successful")
	}

	// Output:
	// HereNow with state successful
}
```

### Swift

```swift
import PubNubSDK

// Initializes a PubNub object with the configuration
let pubnub = PubNub(
  configuration: PubNubConfiguration(
    publishKey: "demo",
    subscribeKey: "demo",
    userId: "myUniqueUserId"
  )
)

// Get presence information for a channel
pubnub.hereNow(on: ["my_channel"]) { result in
  switch result {
  case let .success(presenceByChannel):
    print("Total channels: \(presenceByChannel.count)")
    print("Total occupancy across all channels: \(presenceByChannel.totalOccupancy)")

    if let myChannelPresence = presenceByChannel["my_channel"] {
      // Print the occupancy for the channel
      print("The occupancy for `my_channel` is \(myChannelPresence.occupancy)")
      // Iterating over each occupant in the channel and printing their UUID
      myChannelPresence.occupants.forEach { occupant in
        print("Occupant UUID: \(occupant)")
      }
    }
  case let .failure(error):
    print("Failed hereNow Response: \(error.localizedDescription)")
  }
}
```

Most other SDKs document the same call in the Here Now section of their Presence API reference, for example [PHP](https://www.pubnub.com/docs/sdks/php/api-reference/presence.md#here-now) or [Ruby](https://www.pubnub.com/docs/sdks/ruby/api-reference/presence.md#here-now).

An occupant with no state set returns `null` (or your language's equivalent empty value) instead of an object. Requesting state costs nothing extra when the channel has none to return.

## Get only the occupancy count

Set `includeUUIDs` (or `include_uuids`) to `false`, or `limit` to `0`, when you only need the number, such as an "N people online" badge that never lists who they are.

### JavaScript

```javascript
try {
  const response = await pubnub.hereNow({
    channels: ['my_channel'],
    includeUUIDs: false,
  });
  console.log('hereNow response:', response);
} catch (error) {
  console.error(`hereNow failed with error: ${error}`);
}
```

### Python

```python
here_now = pubnub.here_now() \
    .channels(["chats.room1", "chats.room2"]) \
    .include_uuids(False) \
    .sync()
```

The response shape stays the same size regardless of how many clients are on the channel, because no member list comes back. Refer to [Occupancy](https://www.pubnub.com/docs/presence/occupancy.md#count-only-mode-keeps-the-response-flat) for why that matters on a busy channel, and to your platform's [API reference](https://www.pubnub.com/docs/sdks.md) for the exact parameter name.

## Query a channel group instead of listing channels

Pass a [channel group](https://www.pubnub.com/docs/architecture/core-concepts.md#channel) name instead of a channel list when your subscribers use a wildcard pattern. `Here Now` doesn't accept a wildcard itself, only a fixed channel, a list of channels, or a channel group.

### JavaScript

```javascript
try {
  const response = await pubnub.hereNow({
    channelGroups: ['my_channel_group'],
  });
  console.log('hereNow response:', response);
} catch (error) {
  console.error(`hereNow failed with error: ${error}`);
}
```

### Kotlin

```kotlin
pubnub.hereNow(
    channelGroups = listOf("cg1", "cg2", "cg3"), // who is present on those channels groups
    includeState = true, // include state with request (false by default)
    includeUUIDs = true // if false, only shows occupancy count
).async { result: Result<PNHereNowResult> ->
    result.onSuccess { res: PNHereNowResult ->
        res.totalOccupancy
    }.onFailure { e ->
        // handle error
        e.message
        e.statusCode
        e.pubnubError
    }
}
```

Refer to [Channels and channel naming](https://www.pubnub.com/docs/pub-sub/subscribe/channels.md#a-convention-decides-what-you-can-address-later) for how one naming convention feeds both a wildcard subscription and the channel group you query here.

## Page past the occupant limit

A single `Here Now` call returns up to 1,000 occupants per channel, and you paginate past that with `offset`. Fetch successive pages by increasing `offset` by your `limit` each time, until a response returns fewer occupants than you asked for.

```javascript
// First page: occupants 0-99
const page1 = await pubnub.hereNow({ channels: ['chats.megachat'], limit: 100 });

// Next page: occupants 100-199
const page2 = await pubnub.hereNow({ channels: ['chats.megachat'], limit: 100, offset: 100 });
```

The `occupancy` field on every page reports the same true, uncapped total. Only the `occupants` array is paginated.

:::tip Debug Console
To check who is subscribed to a channel without writing code, use the **Presence** tab of the Debug Console in the [Admin Portal](https://admin.pubnub.com/).
:::

## Related tasks

* [Get subscribed channels for a user](https://www.pubnub.com/docs/presence/get-subscribed-channels-for-user.md). Call `Where Now` for a specific User ID.
* [Set and get presence state](https://www.pubnub.com/docs/presence/set-and-get-presence-state.md). Attach the custom state a `Here Now` response can include per occupant.
* [Receive presence events](https://www.pubnub.com/docs/presence/receive-presence-events.md). Keep an occupant list current after this initial fetch, without polling.
* [Occupancy](https://www.pubnub.com/docs/presence/occupancy.md). Response caching, why count-only mode stays flat, and behavior in interval mode.
* [Presence](https://www.pubnub.com/docs/presence/overview.md). How presence data is enabled and delivered.
* [Presence Management](https://www.pubnub.com/docs/presence/overview.md). Configure which channels track presence.
* [API limits](https://www.pubnub.com/docs/architecture/limits.md#presence). `Here Now` cache time and occupant cap.

Last updated at: 2026-10-01T14:47:31.000Z
