Real-Time Backend

Data Channels

Figma lets 100 collaborators move cursors and edit one file at once without lag. Cursor positions update 60 times/sec from each participant. That's 100 * 60 = 6000 messages/sec - over WebSocket that would kill the server. How does it work?

  • **Figma** uses RTCDataChannel for cursor positions (unordered, unreliable) and a separate channel for objects (ordered, reliable). P2P between users in the same room offloads the servers and cuts latency from ~80ms to ~15ms for users in nearby regions.
  • **Discord** Go Live (screen share) and Video Calls use DataChannels for auxiliary data: speaking indicators, noise suppression controls, hardware stats. Media flows over WebRTC media tracks, control data over DataChannel.
  • **agar.io** in its early years used DataChannels for P2P game state sync among 4-8 players in one room - it let the product launch without dedicated game servers. When it scaled past 8 players, it moved to a WebSocket server.
  • **WebTorrent** (BitTorrent in the browser) uses RTCDataChannel for peer-to-peer file chunk transfer between browsers. 1M+ users transfer files with no central server, only a torrent tracker for initial peer discovery.

RTCDataChannel

RTCDataChannel is a mechanism for sending arbitrary data between browsers directly over P2P, on top of SCTP/DTLS. Unlike WebSocket, data flows without an intermediate server. Latency is set only by the network between peers, not by the round-trip to a server.

SCTP (Stream Control Transmission Protocol) under data channels supports stream multiplexing, partial reliability, and out-of-order delivery. This makes it fundamentally different from TCP (always ordered+reliable) and UDP (always unordered+unreliable).

What's the inherent difference between RTCDataChannel and WebSocket for transferring data between two clients?

Ordered vs Unordered

The `ordered` parameter decides whether message delivery order is guaranteed. With `ordered: true` (default) SCTP buffers packets and hands them to the app strictly in order, like TCP. With `ordered: false`, messages are handed off as they arrive, possibly out of order.

Unordered delivery removes head-of-line blocking, the situation where losing one packet delays all subsequent ones. For real-time data (player positions, cursor movement in Figma) the freshest message matters more than recovering a stale one.

Google Docs implements collaborative editing via Operational Transformation. Which ordering mode fits the editing operation stream?

Reliable vs Unreliable

The `maxRetransmits` and `maxPacketLifetime` parameters switch the channel to partial reliability. `maxRetransmits: 0` is fire-and-forget, like UDP. `maxPacketLifetime: 100` means retransmit only for 100ms, then drop.

Discord uses RTCDataChannel to transfer game overlay and presence statuses - unordered, maxRetransmits: 0. Figma uses an ordered reliable channel to sync vector objects, and an unordered unreliable channel for cursor positions (~60 updates/sec from each collaborator).

An app sends mouse position updates ~60 times/sec. A position packet must arrive within 33ms or it's not needed. What's the right config?

Data Channels in games

Browser games with P2P multiplayer (and apps like Figma, Miro) use multiple data channels simultaneously, each with parameters tuned to its data type. This mirrors the UDP/TCP split in native games.

Theoretical RTCDataChannel bandwidth per message is ~256KB (Chrome). Netflix experiments with P2P CDN via DataChannels for peer-assisted delivery showed a 40% reduction in origin load at sufficient peer density. agar.io (15M MAU) used DataChannels for multiplayer before moving to dedicated servers as it scaled.

RTCDataChannel is slower than WebSocket because P2P has no bandwidth guarantee

RTCDataChannel is faster than WebSocket for peer-to-peer data, because it cuts out the server round-trip. Latency = RTT between peers, not 2*RTT through the server.

WebSocket: client A -> server -> client B = 2 RTT. DataChannel: client A -> client B = 1 RTT. With 50ms between peers and 100ms to the server, WebSocket adds 150ms latency vs. 50ms over P2P. Critical for games where the perceived latency threshold is around 100ms.

In a P2P browser game with 4 players (Mesh topology), how many RTCDataChannel connections are needed for positions, if each player must receive data from all others?

Key takeaways

  • **RTCDataChannel** runs on top of SCTP/DTLS and provides P2P data transfer with no server. It's created before the SDP offer/answer.
  • **ordered: false** removes head-of-line blocking, critical for real-time data where freshness beats recovering a stale packet.
  • **maxRetransmits / maxPacketLifetime** let you tune partial reliability: a trade-off between delivery guarantee and latency.
  • **Multi-channel pattern**: several channels with different parameters for different data types, like the TCP+UDP split in native games.

Related topics

DataChannels complement the media side of WebRTC and apply across various topologies:

  • STUN and TURN — DataChannel connections also go through ICE with STUN/TURN - the same NAT traversal problems as media
  • Media Streams — Media tracks and DataChannels multiplex into one RTCPeerConnection; DataChannel is often used for control messages to media streams
  • MCU vs SFU vs Mesh — DataChannels in Mesh topology need N*(N-1)/2 connections - which is what makes Mesh inefficient at scale

Вопросы для размышления

  • Figma does collaborative editing through a server, but cursor positions through P2P DataChannel. Why exactly that split?
  • In a game with 8 players, Mesh gives 28 peer connections per player. At what number of participants does Mesh become impractical, and why?
  • Are maxRetransmits: 0 and maxPacketLifetime: 0 the same thing? What happens to the packet in each case?

Связанные уроки

  • rt-57 — DataChannel connections go through the same STUN/TURN NAT traversal as media
  • rt-55 — DataChannel is created on top of the RTCPeerConnection covered in WebRTC basics
  • net-14-udp
Data Channels

0

1

Sign In