---
source_url: https://www.pubnub.com/docs/sdks/rust/api-reference/presence
title: Presence API for Rust SDK
updated_at: 2026-05-22T11:07:49.191Z
sdk_name: PubNub Rust SDK
sdk_version: 0.7.0
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Presence API for Rust SDK

PubNub Rust SDK, use the latest version: 0.7.0

Install:

```bash
cargo add pubnub@0.7.0
```

Presence lets you track who is online or offline and store custom state information. Presence shows:

* When a user has joined or left a channel
* How many users are subscribed to a particular channel (occupancy)
* Which channels a user or device is subscribed to
* Presence state associated with these users

Learn more about our Presence feature in the [Presence overview](https://www.pubnub.com/docs/general/presence/overview).

##### Available in features

Add any of the following features to `Cargo.toml` to use this API:

```yaml
[dependencies]
# full
pubnub = { version = "0.7.0", features = ["full"] }
# Presence
pubnub = { version = "0.7.0", features = ["presence"] }
```

For a list of all features, refer to [Available features](https://www.pubnub.com/docs/sdks/rust#available-features).

## Here now

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/). For information on how to receive presence events and what those events are, refer to [Presence Events](https://www.pubnub.com/docs/general/presence/presence-events#subscribe-to-presence-channel).
:::

This method returns information about the current state of a channel, including a list of unique user IDs (universally unique identifiers, UUIDs) currently subscribed to the channel and the total occupancy count of the channel.

:::note Cache
This method has a 3-second response cache time.
:::

### Method(s)

To call `here_now()`, use the following method in the Rust SDK:

```rust
pubnub
    .here_now()
    .channels(Vec<String>)
    .channel_groups(Vec<String>)
    .include_state(bool)
    .include_user_ids(bool)
    .limit(usize)
    .offset(Option<usize>)
    .execute()
```

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| channels() | Vec<String> | Optional |  | The channels to get the details of. |
| channel_groups() | Vec<String> | Optional |  | The channel groups to get the details of. |
| include_state() | bool | Optional | `false` | If `true`, the response will include the presence states of the users for `channels`/`channelGroups`. |
| include_user_ids() | bool | Optional | `true` | If true, the response will include the user IDs of the connected clients. |
| limit() | usize | Optional | `1000` | Maximum number of occupants to return per channel. Valid range: `0-1000`. Use `0` to get occupancy counts without user details. |
| offset() | Option<usize> | Optional | `None` | Zero-based starting index for pagination. Returns occupants starting from this position in the list. Must be `>= 0`. Requires `limit > 0`. Use with `limit` to paginate through large occupant lists. This parameter is only included in the request when `offset > 0`. |

### Sample code

#### Get a list of channels, their occupancy, and individual occupants' states

```rust
    let channels_now = client
        .here_now()
        .channels(["my_channel".into(), "other_channel".into()].to_vec())
        .include_state(true)
        .include_user_id(true)
        .execute()
        .await?;

    println!("All channels data: {:?}\n", channels_now);

    channels_now.iter().for_each(|channel| {
        println!("Channel: {}", channel.name);
        println!("Occupancy: {}", channel.occupancy);
        println!("Occupants: {:?}", channel.occupants);

        channel
            .occupants
            .iter()
            .for_each(|occupant| println!("Occupant: {:?}", occupant));

        println!();
    });
```

### Returns

The `here_now()` operation returns a `HereNowResult`, which contains the following fields:

| Field | Type | Description |
| --- | --- | --- |
| `total_channels` | `u32` | Total number of channels. |
| `total_occupancy` | `u32` | Number of all users in the provided channels. |
| `channels` | `Vec<HereNowChannel>` | A vector with values of `HereNowChannel` for each channel. Refer to [HereNowChannel](#herenowchannel) for more details. |

#### HereNowChannel

| Field | Type | Description |
| --- | --- | --- |
| `name` | `String` | Channel name. |
| `occupancy` | `u32` | Number of all users in the channel. |
| `occupants` | `Vec<HereNowUser>` | A vector of `HereNowUser`, refer to [HereNowUser](#herenowuser) for more details. |

#### HereNowUser

| Field | Type | Description |
| --- | --- | --- |
| `user_id` | `String` | Id of the user. |
| `state` | `serde_json::Value` | State of the user. If you're not using the default `serde` serialization framework, this field is of type `Vec<u8>`. |

## Where now

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/). For information on how to receive presence events and what those events are, refer to [Presence Events](https://www.pubnub.com/docs/general/presence/presence-events#subscribe-to-presence-channel).
:::

You can obtain information about the current list of channels to which a user ID is subscribed to by calling the `where_now()` function in your application.

:::note Timeout events
If the app is killed/crashes and restarted (or the page containing the PubNub instance is refreshed on the browser) within the heartbeat window no timeout event is generated.
:::

### Method(s)

To call `where_now()`, use the following method in the Rust SDK:

```rust
pubnub
    .where_now()
    .user_id(String)
    .execute()
```

| Parameter | Description |
| --- | --- |
| `user_id()`Type: `String`Default: User ID provided in PubNub config | User ID to get the current channel subscriptions for. |

### Sample code

```rust
    let where_user = client.where_now().user_id("user_id").execute().await?;

    println!("User channels: {:?}", where_user);
```

### Returns

The `where_now()` operation returns a `WhereNowResult`, which contains the following fields:

| Field | Type | Description |
| --- | --- | --- |
| `channels` | `Vec<String>` | List of channels where the user ID is present. |

## User state

:::warning Requires Presence
This method requires that the Presence add-on is [enabled](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) for your key in the [Admin Portal](https://admin.pubnub.com/). For information on how to receive presence events and what those events are, refer to [Presence Events](https://www.pubnub.com/docs/general/presence/presence-events#subscribe-to-presence-channel).
:::

The state API is used to set/get key/value pairs specific to a subscriber user ID.

State information is supplied as a JSON object of key/value pairs.

:::note Presence state format
Presence state must be expressed as a JSON object.
:::

### Method(s)

To manage presence state, use any of the following method(s) in the Rust SDK:

#### Set state

```rust
pubnub
    .set_presence_state(T: Serialize)
    .channels(Vec<String>)
    .channel_groups(Vec<String>)
    .user_id(String)
    .execute()
```

| Parameter | Description |
| --- | --- |
| `set_presence_state()` *Type: `T: Serialize`Default: n/a | The state to set expressed as a JSON object. |
| `channels()`Type: `Vec<String>`Default: n/a | Channels to set state on. |
| `channel_groups()`Type: `Vec<String>`Default: n/a | Channel groups to set state on. |
| `user_id()`Type: `String`Default: User ID provided in PubNub config | The user ID to set state for. |

#### Get state

```rust
pubnub
    .get_presence_state()
    .channels(Vec<String>)
    .channel_groups(Vec<String>)
    .user_id(String)
    .execute()
```

| Parameter | Description |
| --- | --- |
| `channels()`Type: `Vec<String>`Default: n/a | Channels to get state of. |
| `channel_groups()`Type: `Vec<String>`Default: n/a | Channel groups to set state of. |
| `user_id()`Type: `String`Default: User ID provided in PubNub config | The user ID to get state for. |

### Sample code

```rust
                    is_doing: "Something".to_string(),
                    flag: true,
                },
            ),
            (
                "other_channel".to_string(),
                State {
                    is_doing: "Oh no".to_string(),
                    flag: false,
                },
            ),
        ]))
        .channels(["my_channel".into(), "other_channel".into()].to_vec())
        .user_id("user_id")
        .execute()
        .await?;

    client
        .set_presence_state(State {
            is_doing: "Nothing... Just hanging around...".into(),
            flag: false,
        })
        .channels(["my_channel".into(), "other_channel".into()].to_vec())
        .user_id("user_id")
        .execute()
        .await?;

    println!("State set!");
    println!();

    let states = client
        .get_presence_state()
        .channels(["my_channel".into(), "other_channel".into()].to_vec())
        .user_id("user_id")
        .execute()
        .await?;

    println!("All channels state: {:?}", states);

    states.iter().for_each(|channel| {
        println!("Channel: {}", channel.channel);
```

### Returns

The `set_presence_state()` operation returns a `SetStateResult` which contains the following fields:

| Field | Type | Description |
| --- | --- | --- |
| `channel` | `String` | The channel the state was set on. |
| `state` | `serde_json::Value` | State of the user. If you're not using the default `serde` serialization framework, this field is of type `Vec<u8>`. |

The `get_presence_state()` operation returns a `GetStateResult` which contains the following fields:

| Field | Type | Description |
| --- | --- | --- |
| `state` | `Vec<GetStateInfo>` | Vector of [GetStateInfo](#getstateinfo) objects. |

#### GetStateInfo

The `GetStateInfo` object contains the following fields:

| Field | Type | Description |
| --- | --- | --- |
| `channel_name` | `String` | The channel name the state was set on. |
| `state` | `serde_json::Value` | State of the user. If you're not using the default `serde` serialization framework, this field is of type `Vec<u8>`. |