Data messages

Send custom data packets between participants in realtime.

Overview

You can publish arbitrary data messages to other participants in the same room from with LocalParticipant.publishData. You can also use RoomService.SendData in the server API.

Delivery options

LiveKit offers two forms of message delivery:

  • Reliable: Messages are delivered in order, with automatic retransmission in the case of packet loss. This is preferable for scenarios where delivery is prioritized over latency, such as in-room chat.
  • Lossy: Each message is sent once, with no ordering guarantee. This is ideal for realtime updates where speed of delivery is a priority.
note

Reliable delivery indicates "best-effort" delivery. It cannot fully guarantee the message will be delivered in all cases. For instance, a receiver that is temporarily disconnected at the moment the message is sent will not receive it. Messages are not buffered on the server and only a limited number of retransmissions are attempted.

Size limits

In the reliable delivery mode, each message can be up to 15KiB in size. The protocol limit is 16KiB for the entire data packet, but LiveKit adds various headers to properly route the messages which reduces the space available for user data.

While some platforms might support larger packet sizes without returning an error, LiveKit recommends this 16KiB limit to maximize compatibility across platforms and address limitations of the Stream Control Transmission Protocol (SCTP). To learn more, see Understanding message size limits.

In the lossy delivery mode, LiveKit recommends even smaller data packets - just 1300 bytes maximum - to stay within the network Maximum Transmit Unit (MTU) of 1400 bytes. Larger messages are fragmented into multiple packets and if any single packet is lost, the whole message is lost with it.

Selective delivery

Messages can be sent either to the entire room or to a subset of participants with the destinationIdentities parameter on the publishData call. To send to the entire room, leave destinationIdentities blank.

Topic

You may have different types and purposes of data messages. To easily differentiate, set the topic field to any string that makes sense for your application.

For example, in a realtime multiplayer game, you might use different topics for chat messages, character position updates, and environment updates.

Usage

const strData = JSON.stringify({some: "data"})
const encoder = new TextEncoder()
const decoder = new TextDecoder()
// publishData takes in a Uint8Array, so we need to convert it
const data = encoder.encode(strData);
// Publish lossy data to the entire room
room.localParticipant.publishData(data, {reliable: false})
// Publish reliable data to a set of participants
room.localParticipant.publishData(data, {reliable: true, destinationIdentities: ['my-participant-identity']})
// Receive data from other participants
room.on(RoomEvent.DataReceived, (payload: Uint8Array, participant: Participant, kind: DataPacket_Kind) => {
const strData = decoder.decode(payload)
...
})