---
source_url: https://www.pubnub.com/docs/general/basics/send-messages
title: Send messages
updated_at: 2026-06-11T11:34:35.042Z
---

> 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


# Send messages

Sending messages is the cornerstone of PubNub. We guarantee that any message you send is delivered worldwide in under 30 ms. Messages arrive in the blink of an eye.

A [PubNub Message](https://www.pubnub.com/docs/general/messages/publish) can contain any kind of serializable data, like objects, numbers and UTF-8 encoded strings. Its format may be plain text, a URL-encoded object, or most commonly, JavaScript Object Notation (JSON). The max size of a message is 32 Kibibytes (KiB). You can check the size of your message payload using our [message size calculator.](https://www.pubnub.com/docs/general/messages/publish#message-size-limit)

:::tip Need larger messages?
Our platform is optimized for payloads up to 32 KiB. PubNub supports larger messages, but increasing the limit requires a verification of compatibility with your use case.
Talk to [our team](https://www.pubnub.com/company/contact-sales/) to discuss increasing the message size limit for your use case.
:::

###### JSON

```json
{
    "content": {
        "type": "text",
        "message": "This is a message!"
    },
    "sender": "Thomas Anderson"
}
```

###### Plain text

```text
"This is a message! Sender: Thomas Anderson"
```

###### URL-encoded object

```url
"%7B%0A%20%20%20%20%22content%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22
type%22%3A%20%22text%22%2C%0A%20%20%20%20%20%20%20%20%22message%22%3A%
20%22This%20is%20a%20message%21%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20
%22sender%22%3A%20%22Thomas%20Anderson%22%0A%7D"
```

After you publish a message, PubNub returns a [response](https://www.pubnub.com/docs/general/messages/publish#send-messages) that includes a timetoken, an exact timestamp (17‑digit value to the nearest 10th nanosecond) of when the message was published. Timetokens help you work with historical messages.

Depending on your needs, you can [change the structure and add a custom type](https://www.pubnub.com/docs/general/messages/type) to your messages, send [small bits of data designed for high volumes](https://www.pubnub.com/docs/general/messages/publish#send-signals), or even [send a file](https://www.pubnub.com/docs/general/files). If you need an extra layer of security, you might want to consider [encrypting your messages and files](https://www.pubnub.com/docs/general/setup/data-security).

Regardless of the payload, you always send it to a channel.

Think of a channel as a tunnel that PubNub uses to transmit data between devices. When you send a message, you must specify the channel. You can send a message to one channel at a time.

In the code below, the message of the `text-message` custom type is sent to the channel with the ID of `my_channel`. Note that not all SDKs yet support sending messages with a custom message type.

###### JavaScript

```javascript
pubnub.publish(
  {
    channel: "my_channel",
    message: {"text": "This is my first realtime message!"},
    customMessageType: "text-message"
  },
  function(status, response) {
    console.log(status);
    console.log(response);
  }
);
```

###### Swift

```swift
pubnub.publish(
  channel: "my_channel",
  message: ["text": "This is my first realtime message!"]
  customMessageType: "text-message",
){ result in
  switch result {
    case let .success(response):
      print("succeeded: \(response)")

    case let .failure(error):
      print("failed: \(error.localizedDescription)")
  }
}
```

###### Objective-C

```objectivec
self.client.publish()
    .channel(@"my_channel")
    .message(@"This is my first realtime message!")
    .customMessageType(@"text-message")
    .performWithCompletion(^(PNPublishStatus *status) {

    if (!status.isError) {

        // Message successfully published to specified channel.
    }
    else {

        /**
         Handle message publish error. Check 'category' property to find
         out possible reason because of which request did fail.
         Review 'errorData' property (which has PNErrorData data type) of status
         object to get additional information about issue.

         Request can be resent using: [status retry];
         */
    }
});
```

###### Java

```java
JsonObject data = new JsonObject();
data.addProperty("text", "This is my first realtime message!");

Channel channel = pubnub.channel("my_channel");

channel.publish(data)
  .customMessageType("text-message")
  .async(result -> { /* check result */ });
```

###### C#

```csharp
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("text", "This is my first realtime message!");

pubnub.Publish()
  .Channel("my_channel")
  .Message(data)
  .Execute(new PNPublishResultExt(
    (result, status) => {
      if (status.isError) {
        Console.WriteLine("status code: " + status.ErrorData.Information);
      }
      else {
        Console.WriteLine("timetoken: " + result.Timetoken.ToString());
      }
    }
  ));
```

###### Python

```python
def publish_callback(result, status):
    if status.is_error():
        print(status.status_code, status.error_data.__dict__)
    else:
        print(result.timetoken)

pubnub.publish()\
  .channel("my_channel") \
  .message({"text": "This is my first realtime message!"})\
  .custom_message_type("text-message") \
  .pn_async(publish_callback)
```

###### Dart

```dart
var result = await pubnub.publish('my_channel', 'This is my first realtime message!');
```

###### Kotlin

```kotlin
val channel = pubnub.channel("myChannel")

val myMessage = JsonObject().apply {
    addProperty("text", "this is my first realtime message!")
}

channel.publish( 
  message = myMessage, 
  customMessageType = "text-message"
  ).async { result ->
    result.onFailure { exception ->
        println("Error while publishing")
        exception.printStackTrace()
    }.onSuccess { value ->
        println("Message sent, timetoken: ${value.timetoken}")
    }
}
```

You don't need to create a channel before you send a message to it. A channel is created automatically when the first message is sent. All you need to do is provide the channel name. Try to be as descriptive as possible and adopt our [channel naming convention](https://www.pubnub.com/docs/general/channels/channel-naming) in order not to miss out on certain PubNub features.

When you've sent your first message, you can check if it's been correctly sent by using the PubNub [Debug Console](https://www.pubnub.com/docs/console/), but now it's only natural to wonder [how to receive messages someone else sent](https://www.pubnub.com/docs/general/basics/receive-messages). Let's look into that.

## Terms in this document

* **Channel** - A pathway for sending and receiving messages between devices, created automatically when you first use it, that can handle any number of users and messages for different communication needs, like 1-1 text chats, group conversations, and other data streaming.
* **Channel pattern** - A way to group and analyze channel data to track performance metrics like message counts and user engagement over time with PubNub Insights.
* **PubNub** - PubNub is a real-time messaging platform that provides APIs and SDKs for building scalable applications. It handles the complex infrastructure of real-time communication, including: Message delivery and persistence, Presence detection, Access control, Push notifications, File sharing, Serverless processing with Functions and Events & Actions, Analytics and monitoring with BizOps Workspace, AI-powered insights with Illuminate.
* **Timetoken** - A unique identifier for each message that represents the number of 100-nanosecond intervals since January 1, 1970, for example, 16200000000000000.
