Data tracks extend LiveKit's realtime track infrastructure beyond audio and video. Publish binary frames from sensors, control systems, or other high-frequency sources. LiveKit handles selective forwarding to subscribers with low latency and high throughput, just like it does for media.
What is a track?
In LiveKit, a track is a stream of frames published by one participant and made available for others to subscribe to. This abstraction is what makes selective forwarding possible. The SFU only forwards frames to participants who subscribe, keeping bandwidth to the minimum required at any given time. This is especially important under degraded network conditions, where forwarding unneeded traffic would worsen congestion.
Data tracks
Until now, tracks have been limited to audio and video. With data tracks, you can publish arbitrary binary data over the same track infrastructure.
With data tracks, you can build features like:
- Teleoperation: Send control commands to remotely operate robots, drones, and other devices.
- Sensor data: Publish readings from IMUs, LiDARs, RGBD cameras, or other sensors at high frequency.
- Telemetry: Stream application-specific metrics and logs in realtime.
- Non-standard media: Stream formats not natively supported by WebRTC, such as MJPEG from edge devices.
See the data tracks documentation for full API details.
How it works
Your application pushes frames onto a published data track for delivery to subscribers. A data track frame is conceptually similar to an audio or video frame — it represents a complete application-level message delivered to subscribers (e.g., sensor reading, control command, pixel buffer, etc.).
As with media tracks, timely delivery is prioritized. Frames are delivered to your application intact and in order when they arrive, but they are not retransmitted, so intermediate frames may be dropped under network pressure.
In contrast to media tracks, publishing and subscribing to data tracks are comparatively lightweight as they do not carry the same codec and processing overhead. There's no practical limit to how many can be published in a room concurrently (the theoretical limit is 65,535). This makes it realistic to model data at the level of individual channels if desirable — for example, one track per sensor or actuator.
Frames also support user timestamps — you can attach an arbitrary 64-bit value to each frame. This is useful for calculating end-to-end latency or associating a frame with its original capture time.
Under the hood
For those curious about the internals, here's the path from push to frame delivery. The same general flow applies on the web, though some details presented here are specific to the Rust implementation and the native SDKs built on it.
Non-blocking push
Pushing a frame hands it off to the track's pipeline task (already spawned at publish time) and returns immediately. The pipeline handles the rest of the process in the background, so your application never blocks at the call site.
End-to-end encryption
If end-to-end encryption is enabled for the room, the frame's payload is encrypted within the pipeline before it leaves the client. Decryption happens on the subscriber side, so the SFU never sees plaintext data.
Packetization
Frames are packetized for transport using a custom format inspired by RTP. The base header is just 12 bytes, excluding extensions, while track-level information such as publisher identity is signaled out-of-band to keep per-packet overhead to the minimum needed for routing and reassembly. The header also supports a forward-compatible extension mechanism, allowing new frame-level metadata to be added in the future without breaking older clients.
The format is designed so the exact header size can be computed before serialization. This lets the packetizer determine precisely how much space remains for payload, maximizing MTU utilization on every packet and avoiding intermediate allocations.
Transport
Packets travel over WebRTC data channels configured for unordered, lossy delivery — one between the publisher and the SFU, and one between the SFU and each subscriber.
Selective forwarding
Once packets reach the SFU, their headers are inspected to look up active subscriptions. Packets are only forwarded to downstream participants who have subscribed to the track, keeping bandwidth usage proportional to actual demand.
Reassembly
On the subscriber side, the process is reversed — packets are routed to the pipeline task for the specific track, decrypted if needed, reordered, and reassembled into a complete frame for delivery to the application.
Getting started
You can use data tracks now with these client SDKs:
Support for additional SDKs is coming soon.
Read the documentation for full setup and API details. To see an example of how you can use data tracks for teleoperating a robot from the browser, check out our teleop example. If you have questions or feedback, post a topic in the Robotics category in our community.