---
source_url: https://www.pubnub.com/docs/pub-sub/subscribe/subscriptions
title: Subscriptions and subscription sets
updated_at: 2026-09-30T07:20:08.000Z
---

# Subscriptions and subscription sets

## Documentation index

To discover more PubNub resources:

1. Fetch [PubNub's llms.txt](https://www.pubnub.com/llms-full.txt) for a list of available pages in Markdown format.
2. Identify relevant URLs from that index.
3. Fetch the target pages.

Do not assume a path exists, always check the index first.

In PubNub, a `Subscription` or `SubscriptionSet` is the object your code uses to control what a client receives. [What a subscription addresses and how one connection carries many of them](https://www.pubnub.com/docs/pub-sub/subscribe/overview.md#what-a-subscription-addresses) is the subscribe model. This page covers:

* which entity each kind of subscription is built from, and what that entity scopes it to
* what actually differs between a `Subscription` and a `SubscriptionSet`, beyond how many entities each one covers
* why some SDKs let you skip holding either object, and what that trade-off costs
* the two ways to build a `SubscriptionSet`, and how it relates to the subscriptions inside it
* why calling `subscribe()` or `unsubscribe()` changes the object's state rather than sending a server-side registration
* the one option you set when you create a subscription, and what it controls
* which parts of the subscribe model are deliberately not properties of the object

One rule holds throughout. A subscription is a local object, not a server-side record. The PubNub network knows only the channels and channel groups named in the SDK's current subscribe request. It has no concept of the `Subscription` object your code is holding. So creating, discarding, or reassigning one has no effect until your code calls `subscribe()` or `unsubscribe()` on it.

## What entity a subscription is built from

Current [SDKs](https://www.pubnub.com/docs/getting-started/available-sdks.md) build a subscription by calling `.subscription()` on an [entity](https://www.pubnub.com/docs/architecture/core-concepts.md#message), and the entity decides what the resulting subscription is scoped to:

| Entity | `.subscription()` returns a subscription scoped to | Refer to |
| --- | --- | --- |
| `Channel` | One channel's messages, signals, and other channel-level events | [Channels](https://www.pubnub.com/docs/pub-sub/subscribe/channels.md) |
| `ChannelGroup` | Every channel currently in that group, as one unit | [Channel group](https://www.pubnub.com/docs/architecture/core-concepts.md#channel) |
| `UserMetadata` | App Context events for that user's own metadata and memberships | [App Context](https://www.pubnub.com/docs/data-storage/metadata/overview.md) |
| `ChannelMetadata` | App Context events for that channel's own metadata and memberships | [App Context](https://www.pubnub.com/docs/data-storage/metadata/overview.md) |

Each entity is created from the PubNub client, and `.subscription()` on it returns a plain object. Constructing it does nothing on the network until you call `subscribe()` on the result.

SDKs that predate entities have no `.subscription()` call at all. Refer to [SDK entities](https://www.pubnub.com/docs/architecture/core-concepts.md#message) for that split, and to [Listener scope follows the subscription, not the channel name](https://www.pubnub.com/docs/pub-sub/subscribe/event-listeners.md#listener-scope-follows-the-subscription-not-the-channel-name) for what the split means for the handlers you attach.

## Whether to use a subscription or a set

Both objects deliver the same event types through the same handlers. The difference is where a handler's boundary sits.

* A `Subscription` scoped to one entity keeps that entity's events isolated from every other entity's. A handler registered on it never has to inspect the channel name to know what it's looking at, because nothing else can reach that handler.
* A `SubscriptionSet` removes that isolation on purpose. One handler runs for every member's events, so logic that should behave identically across entities needs to exist only once, instead of copied onto several `Subscription` objects.

|  | `Subscription` | `SubscriptionSet` |
| --- | --- | --- |
| Built from | one entity | several entities, or several existing `Subscription` objects |
| A handler registered on it fires for | only that entity's events | every member's events |
| Calling `subscribe()` or `unsubscribe()` on it | activates or deactivates that one entity | activates or deactivates every member at once |

Every event still carries the channel it arrived on, so a handler on a set can recover per-entity behavior by branching on that field. A handler on a single `Subscription` has no such branch to write, because nothing else ever reaches it.

## Whether to let the client manage subscriptions for you

Some SDKs also expose a client-level `subscribe()` that takes channel and channel group names directly paired with a client-level `addListener()` for handlers. This isn't a remnant from before entities existed. All three fully support the `Subscription` and `SubscriptionSet` objects described on this page, and keep the client-level call as a second, permanent way to reach the same result. Check your SDK's [API reference](https://www.pubnub.com/docs/sdks.md) before assuming either holds for your specific SDK version.

Choosing it trades away the granularity described in [Whether to use a subscription or a set](#whether-to-use-a-subscription-or-a-set), on purpose. Every channel and channel group you name this way lands in one scope the client keeps for you. Every handler you register at the client level then fires for all of it, the same way one ever-growing `SubscriptionSet` would. That's the point: no entity to create first, no `Subscription` variable to hold onto, no set to assemble by hand. The cost is the same one a `SubscriptionSet` carries: you can't isolate one channel's handling from another's without branching on the event's channel field yourself inside a shared handler.

## Two ways to build a subscription set

A `SubscriptionSet` groups several subscriptions so that one `subscribe()` call, one `unsubscribe()` call, and one handler registration cover all of them. There are two ways to build one, and they start from opposite ends:

* **From names or entities directly.** Some SDKs let you ask the client for a set in one call, without creating each member subscription yourself first, for example `pubnub.subscriptionSet({ channels: ['ch1', 'ch2'] })` from channel names. A few SDKs accept a mixed list of entities the same way, so one call can build a set covering a `Channel`, a `ChannelGroup`, and a `UserMetadata` object together.
* **From subscriptions you already created.** Combine existing `Subscription` objects into a set, for example by calling `.addSubscription()` on one and passing another. This is the path that fits an application built incrementally. One component created a subscription for its own channel earlier, and a second component now needs to fold it into a shared set.

The examples below build two entity-scoped subscriptions and combine them into one set before subscribing. Method names differ between SDKs, and not every SDK that supports entities exposes this combine operation the same way, so check your platform's API reference for the exact call.

### JavaScript

The following JavaScript is illustrative rather than a working application:

```javascript
const subscription1 = pubnub.channel('chats.room1').subscription({ receivePresenceEvents: true });
const subscription2 = pubnub.channel('chats.room2').subscription();

// Combine two existing subscriptions into a set
const subscriptionSet = subscription1.addSubscription(subscription2);

subscriptionSet.subscribe();
```

### Java

```java
// Create subscriptions
Subscription subscription1 = pubNub.channel("channelName").subscription();
Subscription subscription2 = pubNub.channelGroup("channelGroup").subscription();
Subscription subscription3 = pubNub.channel("channelName03").subscription();

// Combine into a subscription set
SubscriptionSet subscriptionSet = subscription1.plus(subscription2);

// Add another subscription to the set
subscriptionSet.add(subscription3);

// Remove a subscription from the set
subscriptionSet.remove(subscription3);
```

`subscription1.plus(subscription2)` combines two subscriptions, built from a `Channel` and a `ChannelGroup` entity, into one `SubscriptionSet`. `.add()` and `.remove()` manage its membership afterward.

### Kotlin

```kotlin
// Create subscriptions
val subscription1 = pubnub.channel("channelName").subscription()
val subscription2 = pubnub.channelGroup("channelGroup").subscription()
val subscription3 = pubnub.channel("channelName03").subscription()

// Combine into a subscription set
val subscriptionSet = subscription1 + subscription2

// Add another subscription to the set
subscriptionSet += subscription3
// Or
subscriptionSet.add(subscription3)

// Remove a subscription from the set
subscriptionSet -= subscription3
// Or
subscriptionSet.remove(subscription3)
```

`subscription1 + subscription2` combines two subscriptions into a `SubscriptionSet`. `+=` and `.add()` are equivalent ways to add a member afterward, and `-=` and `.remove()` are equivalent ways to remove one.

### C#

```csharp
// Create a subscription from a channel entity
Subscription subscription1 = pubnub.Channel("channelName").Subscription();

// Create a subscription from a channel group entity
Subscription subscription2 = pubnub.ChannelGroup("channelGroupName").Subscription();

// create a subscription set from individual entities
SubscriptionSet subscriptionSet = subscription1.Add(subscription2);

subscriptionSet.Subscribe<object>();
```

`subscription1.Add(subscription2)` combines two subscriptions, built from a `Channel` and a `ChannelGroup` entity, into one `SubscriptionSet`.

### Swift

```swift
// Create a reference to example channel entity
let weatherChannelEntity = pubnub.channel("weather-updates")
// Create a reference to example channel group entity
let newsGroupEntity = pubnub.channelGroup("news-feed")

// Create a SubscriptionSet object from entities above
let subscriptionSet = pubnub.subscription(entities: [weatherChannelEntity, newsGroupEntity])

// Create a subscription for another channel entity to demonstrate
// adding and removing to/from a SubscriptionSet
let sportsSubscription = pubnub.channel("sports-scores").subscription()

// An example of how to add/remove a `sportsSubscription` to/from a SubscriptionSet
subscriptionSet.add(subscription: sportsSubscription)
subscriptionSet.remove(subscription: sportsSubscription)

// Triggers `.subscribe()` on the SubscriptionSet, initiating subscriptions to all contained entities
subscriptionSet.subscribe()
```

`pubnub.subscription(entities:)` builds a set directly from a list of entities. `subscriptionSet.add(subscription:)` and `.remove(subscription:)` then manage the membership of a subscription created separately.

### Unity

```csharp
// Create a subscription from a channel entity
Subscription subscription1 = pubnub.Channel("channelName").Subscription();

// Create a subscription from a channel group entity
Subscription subscription2 = pubnub.ChannelGroup("channelGroupName").Subscription();

// create a subscription set from individual entities
SubscriptionSet subscriptionSet = subscription1.Add(subscription2);

subscriptionSet.Subscribe<object>();
```

`subscription1.Add(subscription2)` combines two subscriptions, built from a `Channel` and a `ChannelGroup` entity, into one `SubscriptionSet`, the same API as the C# SDK.

### Unreal Engine

```cpp
// ACTION REQUIRED: Replace ASample_SubscriptionSet with name of your Actor class
void ASample_SubscriptionSet::SubscriptionSetAddRemoveSubscriptionsSample()
{
	
	//Assumes PubnubClient is created and UserID is set

	// Create a subscription set for tournament management
	TArray<FString> TournamentChannels = {TEXT("tournament_lobby"), TEXT("match_results")};
	UPubnubSubscriptionSet* TournamentSet = PubnubClient->CreateSubscriptionSet(TournamentChannels, TArray<FString>());

	// Create individual subscriptions for different game areas
	UPubnubChannelEntity* PlayerFeedbackChannel = PubnubClient->CreateChannelEntity(TEXT("player_feedback"));
	UPubnubSubscription* FeedbackSubscription = PlayerFeedbackChannel->CreateSubscription();

	UPubnubChannelEntity* AdminNoticesChannel = PubnubClient->CreateChannelEntity(TEXT("admin_notices"));
	UPubnubSubscription* AdminSubscription = AdminNoticesChannel->CreateSubscription();

	// Add individual subscriptions to the tournament set
	TournamentSet->AddSubscription(FeedbackSubscription);
	TournamentSet->AddSubscription(AdminSubscription);

	// Check current subscriptions in the set
	TArray<UPubnubSubscription*> CurrentSubscriptions = TournamentSet->GetSubscriptions();
	UE_LOG(LogTemp, Log, TEXT("Tournament set now contains %d subscriptions"), CurrentSubscriptions.Num());

	// Remove a subscription when no longer needed
	TournamentSet->RemoveSubscription(FeedbackSubscription);

	// Check subscriptions after removal
	TArray<UPubnubSubscription*> SubscriptionsAfterRemoval = TournamentSet->GetSubscriptions();
	UE_LOG(LogTemp, Log, TEXT("Tournament set now contains %d subscriptions after removal"), SubscriptionsAfterRemoval.Num());
}
```

`CreateSubscriptionSet()` builds a set from channel and channel group names. `AddSubscription()` and `RemoveSubscription()` then manage the membership of subscriptions created separately from entities.

A `Subscription` combined into a set this way keeps working on its own: both it and the set it now belongs to can be active at once, independently of each other. Refer to [Listener scope follows the subscription, not the channel name](https://www.pubnub.com/docs/pub-sub/subscribe/event-listeners.md#listener-scope-follows-the-subscription-not-the-channel-name) for how handler scope follows this structure.

## What subscribe and unsubscribe change

`subscribe()` and `unsubscribe()` are the switch on a `Subscription` or `SubscriptionSet`, not a message sent about that specific object. Calling `subscribe()` adds the object's channels and channel groups to the single list the SDK's [subscribe loop](https://www.pubnub.com/docs/pub-sub/subscribe/overview.md#one-connection-carries-every-subscription) is currently requesting. Calling `unsubscribe()` removes them from that list. What the network sees is only the resulting list, never the objects that produced it.

Three consequences follow from that:

* **The object survives unsubscribe().** Unsubscribing stops events from arriving through that object, but the object itself, and every handler still registered on it, remains. Calling `subscribe()` on the same object again resumes it. That is what makes "pause and later resume the same scope" cheaper than discarding the object and rebuilding it from the entity.
* **A SubscriptionSet's subscribe() and unsubscribe() apply to every member at once.** There is no partial subscribe of a set: activating or deactivating it activates or deactivates every subscription it currently contains.
* **unsubscribeAll() is a separate, client-wide operation.** Some SDKs expose it on the PubNub client itself. It stops every subscription and subscription set that client holds in one call, regardless of how many separate objects created them. For the procedure and the calls each SDK exposes, refer to [Stop receiving messages](https://www.pubnub.com/docs/pub-sub/subscribe/stop-receiving-messages.md).

## Whether a subscription receives presence events

Creating a subscription or subscription set takes an options argument alongside the entity, a `SubscriptionOptions` object in SDKs that name the type, or a plain object in SDKs that don't. `receivePresenceEvents` is the one subscription option verified across SDKs today. It decides whether that object's handlers also receive the [presence](https://www.pubnub.com/docs/presence/overview.md) join, leave, and timeout events for its scope. It is not something you can add to an already-created object. Setting it happens at the same call that produces the subscription, as in `pubnub.channel('chats.room1').subscription({ receivePresenceEvents: true })`.

A subscribe filter is not a second subscription option, even though older documentation grouped it with `receivePresenceEvents` this way. Refer to [What a subscription is not](#what-a-subscription-is-not) for where it actually lives. Refer to [Receive presence events](https://www.pubnub.com/docs/presence/receive-presence-events.md) for what the resulting join, leave, and timeout events carry.

## What a subscription is not

* **Not where a subscribe filter lives.** [A subscribe filter expression is a property of the client](https://www.pubnub.com/docs/pub-sub/subscribe/overview.md#filter-on-the-server), applying to every channel and channel group that client subscribes to. Creating a subscription with different intentions per channel does not give each one a different filter. That needs either a separate client instance or client-side filtering in the handler. Refer to [Filter received messages](https://www.pubnub.com/docs/pub-sub/subscribe/filter-received-messages.md).
* **Not where connection status lives.** The status handler reports the shared subscribe connection, so it is registered on the PubNub client object, never on a `Subscription` or `SubscriptionSet`. Refer to [The status handler is the exception](https://www.pubnub.com/docs/pub-sub/subscribe/event-listeners.md#the-status-handler-is-the-exception).
* **Not available in every SDK.** SDKs that predate entities have no `Subscription` or `SubscriptionSet` object at all. They subscribe channels and channel groups directly on the client and register every handler there. That is the only model they offer. Check your platform's API reference before assuming the object model in this page applies. Refer to [SDK entities](https://www.pubnub.com/docs/architecture/core-concepts.md#message).
* **Not the only path, even where it's fully supported.** Some entity-capable SDKs keep a client-level `subscribe()` and `addListener()` alongside `Subscription` and `SubscriptionSet`, as a deliberate second option. Refer to [Whether to let the client manage subscriptions for you](#whether-to-let-the-client-manage-subscriptions-for-you) for more information.

## Next steps

* [Subscribe](https://www.pubnub.com/docs/pub-sub/subscribe/overview.md). What a subscription addresses, multiplexing, and filtering.
* [Event listeners](https://www.pubnub.com/docs/pub-sub/subscribe/event-listeners.md). The handler model and how scope follows the subscription.
* [Receive messages](https://www.pubnub.com/docs/pub-sub/subscribe/receive-messages.md). Create a subscription, register handlers, and start receiving.
* [Stop receiving messages](https://www.pubnub.com/docs/pub-sub/subscribe/stop-receiving-messages.md). Unsubscribe, remove handlers, and unsubscribe from everything at once.
* [Core concepts](https://www.pubnub.com/docs/architecture/core-concepts.md#message). The entity model a subscription is built from.
* [Channels and channel naming](https://www.pubnub.com/docs/pub-sub/subscribe/channels.md). The `Channel` entity's own naming model.

Last updated at: 2026-09-30T07:20:08.000Z
