Control Realtime SFU DataChannel delivery options
Realtime SFU DataChannels now support unordered and partially reliable delivery modes alongside the default reliable and ordered behavior. Applications can configure delivery settings to match payload requirements, choosing between full reliability, unordered delivery, or time/retry-bounded options for use cases like game state, sensor updates, and chat.
Cloudflare Realtime SFU is a WebRTC selective forwarding unit that runs on Cloudflare's global network. It forwards audio, video, and application data between WebRTC clients without requiring you to manage SFU infrastructure or regions.
DataChannels are WebRTC channels for application messages. A client publishes a named DataChannel to Realtime SFU, and the SFU forwards its messages to every client that subscribes to that channel. Use DataChannels for low-latency payloads such as chat messages, game state, sensor updates, and control events.
What changed
Realtime SFU DataChannels now support unordered and partially reliable delivery. DataChannels remain reliable and ordered by default, so existing channels keep their current behavior.
With ordered delivery, a delayed message can block later messages. For game state or sensor updates, recent data may be more useful than recovering an older message. Unordered delivery lets later messages proceed, while partial reliability limits retransmission attempts or delivery time.
Choose delivery behavior
Delivery settings answer two questions: whether newer messages can bypass a delayed message, and when the transport should stop retrying delivery.
Choose the policy that matches how long your payload remains useful:
| Goal | Settings | Use when |
|---|---|---|
| Reliable, ordered delivery (default) | Omit ordered, maxRetransmits, and maxPacketLifeTime |
Messages remain useful and must arrive in order |
| Reliable, unordered delivery | Set ordered: false; omit both retry fields |
Messages remain useful, but later messages should not wait for earlier messages |
| No retries or ordering | Set ordered: false and maxRetransmits: 0 |
The application tolerates message loss and discards out-of-date updates |
| Limited retries | Set maxRetransmits: <COUNT> |
Brief recovery is useful, but repeated retries are not |
| Time-bounded delivery | Set maxPacketLifeTime: <MILLISECONDS> |
A message loses value after a known time window |
ordered controls ordering independently from retries. maxRetransmits and maxPacketLifeTime are alternative retry budgets, so set at most one for each channel. Omit both for reliable delivery, whether ordered or unordered.
Apply the policy end to end
Realtime DataChannels use negotiated IDs, so browsers do not receive delivery settings from the remote peer. Apply the same settings when the publisher creates the local channel, each subscriber pulls the remote channel, and each client calls createDataChannel().
The following example configures unordered delivery with no retransmissions. It begins after you establish a DataChannel transport on both sessions and complete any required SDP exchange. Run the API requests from your backend with APP_ID, APP_TOKEN, PUBLISHER_SESSION_ID, and SUBSCRIBER_SESSION_ID set in your environment.
- On the publisher session, create the local DataChannel:
curl --request POST \
--url "https://rtc.live.cloudflare.com/v1/apps/$APP_ID/sessions/$PUBLISHER_SESSION_ID/datachannels/new" \
--header "Authorization: Bearer $APP_TOKEN" \
--header "Content-Type: application/json" \
--data @- <<EOF
{
"dataChannels": [
{
"location": "local",
"dataChannelName": "player-state",
"ordered": false,
"maxRetransmits": 0
}
]
}
EOF- On each subscriber session, pull the remote DataChannel with the same delivery settings:
curl --request POST \
--url "https://rtc.live.cloudflare.com/v1/apps/$APP_ID/sessions/$SUBSCRIBER_SESSION_ID/datachannels/new" \
--header "Authorization: Bearer $APP_TOKEN" \
--header "Content-Type: application/json" \
--data @- <<EOF
{
"dataChannels": [
{
"location": "remote",
"sessionId": "$PUBLISHER_SESSION_ID",
"dataChannelName": "player-state",
"ordered": false,
"maxRetransmits": 0
}
]
}
EOF- In the publisher and subscriber clients, create the negotiated browser DataChannel with the same settings. In this example,
pcis the activeRTCPeerConnection, andchannelIdis the ID returned by the corresponding API request:
const channel = pc.createDataChannel("player-state", {
negotiated: true,
id: channelId,
ordered: false,
maxRetransmits: 0,
});
Related documentation
Source: original entry ↗