ExpressTURN vs Cloudflare Calls

Cloudflare Calls is an SFU + TURN bundle. ExpressTURN is TURN-only. Pick what fits your stack.

TL;DR

Cloudflare Calls is a SaaS WebRTC platform: SFU + TURN + signaling primitives bundled together. ExpressTURN is a focused TURN provider you bolt onto your own SFU (mediasoup, Janus, LiveKit, Pion, etc.) or peer-to-peer pipeline. If you want a managed SFU, look at Cloudflare Calls. If you've already built or chosen an SFU and just need TURN, ExpressTURN is far cheaper.

Side-by-side

DimensionCloudflare CallsExpressTURN
ScopeSFU + TURN + signaling primitivesTURN-only relay
Pricing modelMetered per-GB (check Cloudflare's current Calls pricing)Free 1 TB; flat $9 for 5 TB
SFU media routingBuilt inN/A — you bring your own SFU
Lock-inCloudflare-specific APIStandard RFC 5766/8656; switch any time
Network footprintCloudflare's global edge20+ regions, dedicated to TURN
Custom server-side logicLimited to what their API exposesYour own SFU, full control

When Cloudflare Calls is the right choice

  • You need an SFU and don't want to operate one. Cloudflare runs the media routing for you.
  • You're already heavily invested in Cloudflare's stack (Workers, R2, D1) and prefer one vendor.
  • Your bandwidth profile is small enough that metered pricing won't surprise you.

When ExpressTURN is the right choice

  • You've already chosen an SFU (mediasoup, Janus, LiveKit, OvenMediaEngine, Pion) — Cloudflare Calls doesn't add value, just locks you in.
  • You're doing peer-to-peer (PeerJS, simple-peer, plain WebRTC) and just need a relay fallback.
  • You want flat predictable pricing instead of per-GB metering.
  • You want the option to switch TURN providers later without rewriting your media path.

Hybrid pattern

Some teams use Cloudflare Workers for signaling, run their own SFU on a VPS, and use ExpressTURN for relay. Each piece is best-of-breed and replaceable.

Migration to TURN-only

If you're considering moving off Cloudflare Calls and onto your own SFU + ExpressTURN, the TURN piece looks like:

const pc = new RTCPeerConnection({
  iceServers: [
    { urls: 'stun:stun.expressturn.com:3478' },
    {
      urls: ['turn:relay1.expressturn.com:3478?transport=udp',
             'turns:relay1.expressturn.com:443?transport=tcp'],
      username: 'YOUR_EXPRESSTURN_USERNAME',
      credential: 'YOUR_EXPRESSTURN_PASSWORD'
    }
  ]
});

The harder part is the SFU swap, not the TURN swap. See our mediasoup, LiveKit, Janus, and Pion recipes.

Bring your own SFU. We'll be your relay.

Sign Up Free

Related: vs Twilio · TURN for streaming