Cloudflare Calls: Turning the edge into a single SFU
Cloudflare Calls has moved into open beta and is available through the Cloudflare Dashboard. The service lets developers build real-time audio and video applications with standard WebRTC APIs while relying on Cloudflare's network to serve as one distributed Selective Forwarding Unit (SFU).
Why WebRTC needs an SFU
WebRTC remains the only way to send UDP traffic from a web browser. Everything else relies on TCP and its associated head-of-line blocking, which makes WebRTC the transport of choice for low-latency, real-time interactions like conferencing and interactive gaming.
Early WebRTC applications often start as peer-to-peer. That approach works for small groups, but scales poorly: every client must send to all n-1 other participants, driving near-exponential bandwidth growth as rooms grow. SFUs—media routing hubs that selectively forward streams between participants—cut that burden substantially and are typically hosted in data centers where connectivity is better than on home networks.

That server-side element complicates a modern application, though. Developers must decide where to host the SFU, how to assign clients to servers, how many participants a room can support, whether custom SDKs are required, and how to monitor and operate the infrastructure. Despite these hurdles, WebRTC remains central across a range of new use cases: AI startups are building real-time conversational agents, cars stream camera feeds to phones, and video conferencing continues to thrive.
Cloudflare has been involved with WebRTC since 2022, when Cloudflare Stream added support for the WHIP and WHEP protocols. That experience informed the goals behind Calls:
- Put every WebRTC component—DTLS, ICE, STUN, SRTP, SCTP—on Anycast with a single IP address.
- Avoid forcing an SDK, since the native WebRTC APIs should suffice for novel uses.
- Run on all 310+ Cloudflare locations, using every server instead of a subset.
- Exchange the offer and answer over HTTP, keeping client interactions to a single PeerConnection.
One network, many edge servers
Cloudflare's core business is running a caching HTTP reverse proxy. Calls poses a harder question: how to make a large-distributed stateful system feel like a single machine. The answer is that every PeerConnection attaches automatically to the closest data center, not to a fixed server. Connections spread across the Anycast network, minimizing last-mile latency. Roughly 95% of the Internet-connected population sits within 50ms of a Cloudflare data center, and once media enters the network, it can be routed over Cloudflare's own backbone.

Distributed connections create more opportunities for retransmissions and bandwidth adjustments closer to the end user.
No more region selection
Traditional SFU architecture forces a choice of server region, often by picking a location when the first participant joins a room—inefficient if the rest of the group is elsewhere. Calls avoids that entirely. When a client initiates a connection, BGP selects the closest data center, and each edge server handles only the PeerConnections of the clients nearest to it. There's no separate layer of WebRTC load balancing for traffic or compute capacity between servers.
How a PeerConnection gets established
Assigning a server per PeerConnection gets complicated with dual-stack networking. Calls uses a single IPv4 and a single IPv6 address. Cloudflare's L4 load balancer performs consistent hashing on the 4-tuple (client IP, client port, destination IP, destination port), which means ICE connectivity checks land on different physical servers depending on whether the client arrives via IPv4 or IPv6.
The connection doesn't stop there. WebRTC relies on multiple protocols. STUN and TURN handle connectivity establishment; the actual media flows are encrypted over DTLS, which carries most of the session data. Unlike QUIC, DTLS has no connection ID field. So to decrypt and process media, every server must be ready to handle DTLS from any client—but the encryption is negotiated through the HTTPS API's SDP exchange, and the ICE connectivity checks depend on that same API for their credentials. The HTTPS API, DTLS, and ICE traffic all arrive at different servers.

As WebRTCHacks noted in 2022 while examining Cloudflare's WHIP implementation, this distributed setup initially caused slow call setup: STUN responses taking 1.8 seconds at worst, DTLS handshakes requiring retries, and total setup near three seconds versus an observed global average of around 800ms. The fix shows how Calls reconciles running WebRTC across unbundled services. Each server is configured to handle any incoming PeerConnection just in time. When a packet appears for an unknown connection, the server quickly retrieves the negotiated parameters—ufrag, DTLS fingerprint—from the server that handled the SDP exchange, then responds appropriately. It's WebRTC session state formed through consensus across the network, with no single server holding all the context.
Trimming connection setup time
Consensus formation across Cloudflare's network is faster now, but even small delays can have visible side effects. Until recently, a few hundred milliseconds of added latency caused Chrome to classify connections as high-latency networks, even when every subsequent STUN message was answered within 5–10ms. That classification made Chrome hold off on sending USE-CANDIDATE attributes for several seconds, degrading the user experience.

Chrome also sends a DTLS ClientHello before USE-CANDIDATE — behavior seen only in Chrome — so Calls now substitutes DTLS packets for STUN packets carrying USE-CANDIDATE. That change removed the delay, and PeerConnections globally now connect in roughly 100–250ms, including consensus management, STUN, and a full DTLS handshake.

Sessions and tracks replace rooms
Once a PeerConnection is established with Cloudflare, it becomes a Session. A single Session can publish many media tracks or DataChannels, each returning a unique ID. Those tracks can then be subscribed to from any other PeerConnection anywhere, at any point during the connection's lifetime.
Behind the scenes, Cloudflare scales each track using a fan-out architecture of cascading trees: a hierarchy where the root distributes the stream to intermediate nodes, which fan out to end-users. This cuts bandwidth demands at the source and distributes load across the network. It supports everything from 1:1 calls to large many:many broadcasts.

There is no "room" concept in Calls. Each client can push as many tracks into a PeerConnection as bandwidth allows — practically limited by the client side. Application developers own signaling and room logic, and can pull any combination of pushed tracks into a PeerConnection. That makes breakout rooms, plenary sessions, and 1:1 side conversations possible without tearing down PeerConnections or reactivating media tracks.
Bandwidth management is unopinionated: no active restrictions and no cap on track count. The WebRTC Stats API provides packet loss and congestion data, so client-side logic can respond appropriately — for instance, alerting a user on poor Wi-Fi and automatically reducing their active video tracks.
Edge-side NACK handling
The Internet does not guarantee timely, ordered delivery, which is why protocols like TCP include retransmission. For real-time systems, timing is different: a packet that arrives too late to render is useless, but a lost packet can still be recovered if a retransmission arrives within milliseconds. That is where NACKs come in.
A WebRTC receiver continuously checks for loss. Missing packets or sequence number gaps trigger a NACK back to the source requesting retransmission. In peer-to-peer topologies, the source must retransmit for every participant. SFUs typically send NACKs upstream or maintain per-client retransmission buffers.
Calls complicates this because publishers and subscribers each connect to Cloudflare — often different servers in different locations — with possible intermediate data centers via Argo or as part of scaling a track to many subscribers. Many SFUs backpropagate NACKs to the source, wasting precious recovery time. Calls instead handles NACKs at the data center closest to the user, shortening the recovery path and improving the odds of successful retransmission compared to centralized SFUs.
Packet loss can also occur between Cloudflare data centers themselves. Calls generates NACKs within the network at each hop, either recovering the packets locally or backpropagating them toward the publisher.
TURN over Anycast
Calls also provides TURN relay service separately from the SFU. TURN allocates public IP addresses and ports per session to maintain connectivity when direct communication is blocked by NATs or firewalls. Cloudflare's TURN supports multiple ports to work around misbehaving middleboxes:
- TURN-over-UDP on ports 3478 and 53
- TURN-over-TCP on ports 3478 and 80
- TURN-over-TLS on ports 5349 and 443
Like the SFU, TURN runs over Anycast, always connecting clients to the nearest data center.
Open beta pricing
Cloudflare Calls is in open beta and available through the Cloudflare Dashboard, where you can set up an SFU app and/or TURN service in a few clicks. For a limited time, the beta is free; from May 15, 2024, the first terabyte per month is free, with additional usage at $0.05 per real-time gigabyte. Beta users get at least 30 days to move to a paid plan. Inbound traffic to Cloudflare is not charged. Volume pricing is available through your account manager.
Calls is suited for new WebRTC applications. If you have existing SFU or TURN infrastructure, Calls can run alongside it — it speaks standard WebRTC and appears like just another peer, so bridging to it is straightforward. Cloudflare also open sourced its internal conferencing app, Orange Meets, which supports small and large calls with state managed in Workers Durable Objects, screen sharing, client-side noise cancellation, and background blur. It is written in TypeScript and React and available on GitHub.


What comes next
Calls already supports publishing and subscribing to media tracks and DataChannels, with features like simulcasting on the roadmap. The team is hiring for work on WebRTC and other real-time protocols.



