LiveKit Logo



Guides / Working with Rooms / Working with data

Working with data

With LiveKit maintaining room state, you can use it to pass around custom application data. We have a flexible system that enables you to pass messages from both the backend, and between participants.

Participant metadata

LiveKit participants have a metadata field that you could use to store application-specific data. For example, this could be the seat number around a table, or other participant-specific state.

Metadata is encoded in the access token that participants use to connect to the room.

With our server SDKs, you can update the metadata from your backend. LiveKit will broadcast metadata changes to all participants in the room. You can receive these updates by listening to the MetadataUpdated callback/event.

Example: Updating metadata from server API

import { RoomServiceClient } from 'livekit-server-sdk';
const client = new RoomServiceClient("myhost", "api-key", "my secret")
const data = JSON.stringify({
some: "values",
client.updateParticipant("myroom", "participant-identity", data)

Data messages

From both server and clients, LiveKit lets you publish arbitrary data messages to any participants in the room via the LocalParticipant.publishData API. Room data is published to the SFU via WebRTC data channels; and LiveKit server would forward that data to one or more participants in the room.

From the server side, this API is exposed on RoomService as SendData

Since the data is sent via UDP, you have a flexibility in regard to the reliability of delivery. We support both reliable and lossy. In reliable mode, your packets will be retransmitted until they are received. For use-cases such as in-room chat, this is preferable.

When using lossy delivery, we suggest keeping data packets small (under network MTU of 1.4k). If a message is packetized into multiple packets, and a single packet doesn't arrive, your client will not receive the message at all.

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 to everyone in the room
room.localParticipant.publishData(data, DataPacket_Kind.RELIABLE)
// publish to specific participants
room.localParticipant.publishData(data, DataPacket_Kind.LOSSY, ['participant_sid'])
// receive data from other participants
room.on(RoomEvent.DataReceived, (payload: Uint8Array, participant: Participant, kind: DataPacket_Kind) => {
const strData = decoder.decode(payload)