---
source_url: https://www.pubnub.com/docs/faq/pub-sub
title: Pub/Sub FAQ
updated_at: 2026-10-27T09:13:26.000Z
---

# Pub/Sub FAQ

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

Short answers to common questions about [Pub/Sub](https://www.pubnub.com/docs/pub-sub/overview.md).

## In what order do subscribers receive messages?

Subscribers receive messages in timetoken order, but live order holds only within the publisher's region.

PubNub assigns every message a server-side timetoken when it accepts the publish. The timetoken records when PubNub accepted the message, which can differ from when the client sent it. History fetched through [Message Persistence](https://www.pubnub.com/docs/data-storage/message-history/overview.md) returns a channel's messages in timetoken order.

Subscribers in the same region as the publisher receive a channel's live messages in timetoken order. When publishers in different regions publish to the same channel at nearly the same moment, a subscriber can receive messages out of order. The timetoken still shows the correct order, so sorting a channel's messages by timetoken gives every client the same order. Timetoken order applies within a channel, so each channel's messages sort on their own.

A subscriber that falls behind the publish rate may miss messages rather than receive them out of order.

To recover missed messages, enable [Message Persistence](https://www.pubnub.com/docs/data-storage/message-history/overview.md) and fetch from the last timetoken the subscriber received. See [Connection management](https://www.pubnub.com/docs/architecture/connection-management/overview.md) for how clients reconnect.

## Can I use PubNub to track moving objects?

Yes. Publish each location update to a channel, and PubNub gives it a timetoken that sets its order. Subscribers in the same region as the publisher receive updates in timetoken order. If devices publish from different regions, sort the updates by timetoken.

Plan for missed updates. A subscriber misses updates in two cases:

* It falls behind the publish rate.
* It stays disconnected longer than the subscriber buffer holds messages.

For live location, that's often fine, because the next update replaces the last one. If you need the complete track, enable [Message Persistence](https://www.pubnub.com/docs/data-storage/message-history/overview.md) and fetch from the last timetoken on reconnect.

To smooth over a gap, interpolate the object's position, or feed updates into a physics model instead of setting the position directly.

## How do I get messages published before I subscribed?

Fetch them from history. A client that subscribes receives only messages published after it subscribes.

To read earlier messages, enable [Message Persistence](https://www.pubnub.com/docs/data-storage/message-history/overview.md), which stores messages, and [retrieve the message history](https://www.pubnub.com/docs/data-storage/message-history/retrieve-message-history.md). Message Persistence retention is 1 or 7 days on the Free plan, 30 days, 3 months, or 6 months on Starter, and 1 year or Unlimited on Pro.

## What happens to messages published when no one is listening?

Nothing changes. PubNub accepts the publish the same way as when someone is subscribed, and publishers and subscribers don't depend on each other. The number of subscribers on a PubNub channel is unlimited.

A channel doesn't store messages itself. A client that was subscribed and briefly disconnects catches up from the subscriber message buffer when it reconnects.

The buffer belongs to the client's subscribe connection, not to a channel, and every channel on that connection shares it. It covers short drops, such as switching from Wi-Fi to mobile data. It isn't storage.

The subscriber message buffer queues messages for a reconnecting client. It holds 100 messages for up to 16 minutes by default, and discards the oldest first (FIFO) when a burst exceeds that size. Larger buffers, for example 300 or 500 messages, can be provisioned per keyset by PubNub Support.

For anything older, or for more messages than the buffer holds, enable [Message Persistence](https://www.pubnub.com/docs/data-storage/message-history/overview.md). It stores each message for your keyset's retention period, unless the publish call sets `storeInHistory` (or `shouldStore`) to `false`. A client that was offline for a long time can then fetch the messages it missed from history.

## How do I keep old messages from reaching subscribers?

Use either of two ways.

* In the [JavaScript SDK](https://www.pubnub.com/docs/sdks/javascript.md) in a browser, set `restore` to `false`. When the network goes down, the SDK tears the client down, so it doesn't catch up on messages published while it was offline. You then subscribe again yourself when the network returns.
* Add a timestamp to each message you publish. Your app can then ignore messages older than a delay you choose, and skip messages it has already received.

## Can I publish to several channels in one call?

No. You publish to one channel at a time. To send the same message to several channels, publish to each one separately. See [Publish model](https://www.pubnub.com/docs/pub-sub/publish/overview.md#publish-model).

## How do I handle publish timeouts?

A publish is a short request on the non-subscribe connection, and that connection has its own timeout. When it elapses, the SDK abandons the request and reports a timeout, which some SDKs surface as a status category such as `PNTimeoutCategory`. The default value and the configuration name differ across SDKs, so check the configuration reference for your SDK in the [SDK docs](https://www.pubnub.com/docs/sdks.md).

By default, PubNub SDKs retry only subscribe operations, using exponential backoff for up to 6 attempts with delays growing from 2 to 150 seconds. Retrying a timed-out publish is therefore your app's decision. You can retry immediately, retry with backoff, tell the user, or drop the message.

Nothing on the server deduplicates publishes, so a retry after an ambiguous failure can produce a duplicate. Design your subscribers to tolerate the occasional duplicate. See [Publish retry](https://www.pubnub.com/docs/pub-sub/publish/overview.md#publish-retry) and [Connection management](https://www.pubnub.com/docs/architecture/connection-management/overview.md#non-subscribe-connection).

## Do I need a new PubNub object for each message?

No. Each PubNub instance opens its own connections on its first API call, so create one instance and keep it for publish, subscribe, Here Now, history, and every other call.

Reuse keeps the connection open, avoids rebuilding the subscribe loop and timers, and keeps your place in the timetoken stream. See [Reuse one client instance](https://www.pubnub.com/docs/architecture/connection-management/overview.md#reuse-one-client-instance).

## What are valid channel names?

A PubNub channel name is built from letters, digits, and the characters `_ - = @ . ! $ # % & ^ ;`. It cannot contain a comma (`,`), colon (`:`), asterisk (`*`), forward slash (`/`), backslash (`\`), whitespace, Unicode Null, or a non-printable ASCII character. Characters outside printable ASCII, such as emoji, are accepted but not recommended.

Channel names cannot exceed 92 UTF-8 characters. PubNub channel names are case-sensitive.

Some invalid characters work in some APIs and SDKs but make others fail, so avoid them everywhere. The period (`.`) splits a channel name into levels, which wildcard subscribe, Function channel patterns, and Access Manager patterns use. See [Channels](https://www.pubnub.com/docs/pub-sub/subscribe/channels.md).

## Can I build threaded messaging with PubNub?

Yes. The [Chat SDK](https://www.pubnub.com/docs/chat/chat-sdk.md), PubNub's SDK for chat apps, has a built-in [threads feature](https://www.pubnub.com/docs/chat/chat-sdk/build/features/messages/threads.md).

With other SDKs, tag each reply with [metadata](https://www.pubnub.com/docs/pub-sub/publish/send-different-message-types.md#attach-metadata-to-a-message) that links it to its parent message, and manage the relationships in your app. For example, use the timetoken of the original message as the thread key. The replies' timetokens then set their order in your UI.

## How do I synchronize several devices?

Use PubNub's time as a shared clock. Each device follows these steps:

1. Record the local time in milliseconds as `start`.
2. Request the current timetoken from `https://ps.pndsn.com/time/0`, or with the SDK's `time()` method.
3. Calculate the request's latency: `delay = now() - start`.
4. Convert the timetoken to milliseconds and add half the latency: `now_ms = timetoken / 10000 + delay / 2`.

All devices can then act at an agreed `now_ms` time, after a short wait that every device agrees on.

This is a basic mechanism, so adapt it to your app. Synchronize the clock again each time the app starts.

## How large can a message be?

PubNub can process messages **up to 2 MB** in size, but the default message payload is limited to 32 KiB. This includes the channel name and any metadata.

For payloads beyond what a message can carry, choose one:

* Store the payload in a database or a storage service, and publish its URL.
* Split the message into parts and put them back together on the subscriber.
* To send files, use [File Sharing](https://www.pubnub.com/docs/data-storage/files/overview.md).

To check a message's size before you publish it, use the [message size calculator](https://www.pubnub.com/docs/pub-sub/publish/send-different-message-types.md#publish-a-message). See [Publish overview](https://www.pubnub.com/docs/pub-sub/publish/overview.md) for publish constraints.

## What happens when a message exceeds the size limit?

PubNub can process messages **up to 2 MB** in size, but the default message payload is limited to 32 KiB. This includes the channel name and any metadata.

PubNub rejects a publish that exceeds the limit. The status code depends on which layer rejects it.

* The load balancer rejects a POST body over the limit with `413`, and a GET request line over the limit with `414`. The response body is JSON from the `Balancer` service, for example `{"status":413,"service":"Balancer","error":true,"message":"Request Entity Too Large"}`.
* If the request reaches the publisher and the publisher counts the message as over the limit, it returns `400` with `[0,"Message Too Large","<timetoken>"]`.

Your SDK reports the error through its publish result or status. To avoid it, check the payload with the [message size calculator](https://www.pubnub.com/docs/pub-sub/publish/send-different-message-types.md#publish-a-message) before you publish. To send more data, see [How large can a message be?](#how-large-can-a-message-be). The error response is described in [Publish model](https://www.pubnub.com/docs/pub-sub/publish/overview.md#publish-model).

## How do I subscribe to several channels at once?

Yes. One client connection can subscribe to many channels in three ways:

* A [subscription set](https://www.pubnub.com/docs/pub-sub/subscribe/receive-messages.md#subscribe-to-several-channels-with-a-subscription-set). It works on every keyset.
* A [channel group](https://www.pubnub.com/docs/pub-sub/subscribe/channels.md). Channel groups require the Stream Controller add-on enabled on the keyset.
* A [wildcard subscribe](#how-do-i-subscribe-to-a-wildcard-channel). Wildcard subscribe requires the Stream Controller add-on with the Wildcard Subscribe option enabled on the keyset.

See [Subscriptions](https://www.pubnub.com/docs/pub-sub/subscribe/subscriptions.md).

## What are channel groups, and how do I add or remove channels?

A channel group is a server-managed, named list of channels that a client subscribes to with a single call. Adding or removing channels in a channel group server-side changes what every subscribed client receives without any client resubscribing. Channel groups require the Stream Controller add-on enabled on the keyset.

You add channels to a group, remove them, and list them with the channel group methods of your SDK, for example in the [JavaScript SDK](https://www.pubnub.com/docs/sdks/javascript/api-reference/channel-groups.md). For how groups compare to wildcard subscribe, see [Channels](https://www.pubnub.com/docs/pub-sub/subscribe/channels.md) and [Subscribe](https://www.pubnub.com/docs/pub-sub/subscribe/overview.md#three-ways-to-name-what-you-receive).

## What are the limits for channel groups and multiplexed subscribes?

A keyset can have any number of channel groups. A single client can subscribe to up to 10 channel groups at a time. Each group holds up to 1,000 channels by default. Paid plans can raise the cap to 2,000 channels per group.

A subscription set doesn't use Stream Controller. PubNub recommends that one client multiplex 10 to 50 channels in a subscribe when it does not use Stream Controller. Neither the server nor the SDKs enforce a channel count. The only hard limit is the length of the subscribe request's Uniform Resource Identifier (URI), because every channel name travels in the request.

See [API limits](https://www.pubnub.com/docs/architecture/limits.md#subscribe).

## How do I subscribe to a wildcard channel?

End the pattern with `.*`. A `*` without the period before it doesn't work and causes a subscribe error. For example, `stocks.*` subscribes to every channel that starts with `stocks.`, such as `stocks.tech`, `stocks.tech.aapl`, and `stocks.healthcare`:

```javascript
pubnub.channel('stocks.*').subscription().subscribe();
```

Wildcard subscribe requires the Stream Controller add-on with the Wildcard Subscribe option enabled on the keyset. See [Channels](https://www.pubnub.com/docs/pub-sub/subscribe/channels.md).

## Can I send JSON objects?

Yes. A message can contain any JSON-serializable data, such as objects, arrays, numbers, and strings.

Don't serialize the JSON yourself. Publish the object as it is, and the SDK serializes and deserializes it for you. String content in a message payload can include any single-byte or multi-byte UTF-8 character.

Special language objects, such as Python classes or functions, don't serialize. Encode binary data as base64 first. PubNub can process messages **up to 2 MB** in size, but the default message payload is limited to 32 KiB. This includes the channel name and any metadata.

## Can I send raw HTML?

Yes, as a string in the message. String content in a message payload can include any single-byte or multi-byte UTF-8 character. PubNub can process messages **up to 2 MB** in size, but the default message payload is limited to 32 KiB. This includes the channel name and any metadata.

## Can I stream binary data?

Yes, after you encode it as text. JSON has no binary type, so binary data has to go into a JSON string.

Base64 is a common encoding. It costs processing time and makes the data about one third larger, because every 3 bytes become 4 characters. This works for small binary content. PubNub can process messages **up to 2 MB** in size, but the default message payload is limited to 32 KiB. This includes the channel name and any metadata.

For larger content, see [How large can a message be?](#how-large-can-a-message-be).

## How do I convert a timetoken to a Unix timestamp?

Divide it by 10,000,000 to get Unix seconds. PubNub assigns every published message a server-side timetoken: a monotonically increasing 17-digit value precise to 100 nanoseconds (10⁻⁷ s), the number of 100-nanosecond intervals since the Unix epoch. For example, `16686902600028961 / 10,000,000 = 1668690260`.

A PubNub timetoken exceeds the largest integer a JavaScript `Number` represents exactly, so increment or compare timetokens with an arbitrary-precision integer type such as `BigInt` rather than with plain numeric arithmetic. See [Publish response and the timetoken](https://www.pubnub.com/docs/pub-sub/publish/overview.md#publish-response-and-the-timetoken).

## Can one subscription cover channels from different keysets?

No. A PubNub instance works within the keyset it was initialized with, so every call on it uses that keyset. Channel names are scoped to one keyset. To work with another keyset, create a second instance. PubNub places no limit on how many client instances you create, though the device or browser may cap concurrent TCP connections. Most apps don't need this, so [contact support](mailto:support@pubnub.com) before you design around it.

## How do I change the list of subscribed channels?

Call `subscribe()` or `unsubscribe()` on a subscription or a subscription set.

* `subscribe()` adds its channels to the client's list.
* `unsubscribe()` removes them.
* `unsubscribeAll()` stops every subscription the client holds.

See [What subscribe and unsubscribe change](https://www.pubnub.com/docs/pub-sub/subscribe/subscriptions.md#what-subscribe-and-unsubscribe-change) and [Stop receiving messages](https://www.pubnub.com/docs/pub-sub/subscribe/stop-receiving-messages.md).

## Why do I get a "Multiplexing not enabled" error?

You used a feature that needs the Stream Controller add-on, and Stream Controller is turned off on your keyset. Subscribing to several channels with a subscription set works without it. These features need it:

* Channel groups.
* Wildcard subscribe, which also needs the Wildcard Subscribe option. New keysets have both turned on by default.
* [Subscribe filters](https://www.pubnub.com/docs/pub-sub/subscribe/filter-received-messages.md).

Turn on Stream Controller for the keyset in the Admin Portal. New keysets have it turned on by default, so if it's off, someone turned it off or asked PubNub Support to. See [Enable the features your app calls](https://www.pubnub.com/docs/architecture/authentication/set-up-your-account.md#enable-the-features-your-app-calls).

## Can I subscribe to a channel group with no channels?

No. Add at least one channel to the group first. Subscribing to an empty group returns a `400` error:

```json
{ "status": 400, "service": "PubSub", "error": true, "message": "Channel group or groups result in empty subscription set" }
```

To keep a group from ever being empty, give it a default channel. See [Channel group events](https://www.pubnub.com/docs/design-patterns/channel-group-events.md).

Last updated at: 2026-10-27T09:13:26.000Z
