Real-Time System Design

System Design · Real-Time System Design

TCP vs. UDP — and Why WebRTC Uses UDP

TCP guarantees everything arrives, in order, at the cost of waiting for it. Real-time media can't afford to wait — here's why WebRTC bets on UDP instead.

8 min read
TCPUDPWebRTC

Almost every "real-time" feature you've ever used — a video call, a multiplayer game, a live-streamed conference — sits on top of a decision made decades ago about which transport protocol to use. That decision isn't a footnote; it shapes what's possible. TCP and UDP solve the same basic problem — moving bytes from one machine to another over an unreliable network — but they make almost opposite trade-offs to do it, and real-time systems live and die by which one they pick.

What TCP actually guarantees

TCP (Transmission Control Protocol) is built around a simple promise: the bytes you send will arrive, completely, and in the exact order you sent them. It keeps that promise with three mechanisms working together.

  • Reliable delivery — every segment is acknowledged. If an acknowledgment doesn't come back in time, TCP assumes the segment was lost and retransmits it, automatically and invisibly to the application.
  • Ordering — segments carry sequence numbers, and the receiving side buffers and reassembles them into the original order before handing anything up to the application, even if the network delivered them out of order.
  • Congestion control — TCP watches for signs of network congestion (lost packets, growing latency) and throttles its own sending rate to avoid making the problem worse for itself and everyone sharing the link.

All three are genuinely useful. They're also the reason TCP has a structural weakness for real-time work: head-of-line blocking. Because TCP delivers data to the application as one strictly ordered stream, a single lost packet stalls everything behind it — even data that already arrived safely — until the lost packet is retransmitted and its place in the sequence is filled. One dropped segment can freeze an entire connection for a round-trip time or more, no matter how much unrelated data was queued up right behind it.

What UDP actually guarantees (almost nothing)

UDP (User Datagram Protocol) makes essentially no promises. It sends discrete datagrams — fire-and-forget — with no acknowledgment, no retransmission, no sequence numbers, and no congestion control built in. A datagram might arrive, might arrive twice, might arrive after the one sent after it, or might never arrive at all, and UDP will never tell you which happened. The application gets whatever shows up, in whatever order it shows up, and it's entirely on the application to notice loss or reordering and decide whether to care.

In exchange for giving up all of that, UDP has almost no per-packet overhead and no head-of-line blocking at all — datagrams are independent of each other by design, so one lost datagram has zero effect on the delivery of the next one. That trade looks reckless until you consider a workload where TCP's guarantees are actively unhelpful.

The insight that flips the trade-off: late data is worse than no data

Most applications assume correctness matters more than timeliness — a bank transfer that arrives three seconds late is still correct and still useful. Real-time audio and video invert that assumption. A video frame that was supposed to render 200ms ago is, by the time it finally arrives, describing a moment that has already passed on a live call. Retransmitting it doesn't fix anything — it just delays every frame after it while the stale one is repaired and reinserted into order, via TCP's head-of-line blocking. The viewer doesn't experience "a bit of packet loss"; they experience the entire call freezing and stuttering.

Correctness vs. timeliness

Most systems are built on the assumption that correctness beats timeliness — better late than wrong. Real-time media flips that: for a live call, a frame that's late is worse than a frame that never showed up at all, because a dropped frame just gets skipped while a late one stalls everything queued behind it. This single inversion is why real-time media protocols are built on UDP rather than TCP.

A codec designed for this reality can simply skip a missing frame, interpolate across it, or gracefully degrade quality for an instant — all better outcomes than freezing the whole stream to wait for a retransmission that will be obsolete the moment it arrives.

How WebRTC actually uses UDP

WebRTC, the browser standard behind most video calling products, commits to this idea directly rather than working around it. Its media path is built on RTP (Real-time Transport Protocol) and RTCP (its companion control protocol for feedback like loss statistics and jitter), both running directly on top of UDP. There's no retransmission layer forcing frames back into strict order — codecs like VP8, VP9, and Opus are explicitly designed to tolerate occasional packet loss, using techniques like forward error correction and graceful quality degradation instead of demanding perfect delivery.

But WebRTC doesn't treat "no reliability, ever" as a universal rule — it treats it as the right default for media, and makes reliability opt-in for everything else. WebRTC's data channels — the mechanism apps use to send arbitrary messages, files, or chat text peer-to-peer — are built on SCTP (Stream Control Transmission Protocol), which itself runs on top of UDP. SCTP can be configured per-channel to add back exactly the guarantees an application needs: ordered delivery, reliable delivery, both, or neither. Sending a chat message or a file chunk that must arrive intact and in order asks SCTP for TCP-like guarantees; sending a rapid stream of game-state updates can ask for none of them. The layering means one connection can carry lossy, time-sensitive video alongside a reliable, ordered file transfer, each tuned to what it actually needs.

When you'd still reach for TCP

None of this makes UDP universally "better" for real-time work — it's better specifically when stale data is worthless. Plenty of latency-sensitive systems still want TCP's guarantees because getting the wrong answer quickly is worse than getting the right answer a little slower.

  • Authoritative game state — a turn-based move, an inventory change, or anything the server treats as the source of truth needs to arrive exactly once and in order; silently dropping it would desync the game in a way no amount of extra frames per second would excuse. (Fast-twitch position updates in an action game are a different story, which is why many game engines run those over UDP while keeping authoritative events reliable.)
  • Chat and signaling messages — a chat message that arrives a second late is still valuable; one that silently vanishes is not. WebRTC's own signaling (the initial handshake that negotiates a call before any media flows) typically happens over a reliable channel for exactly this reason.
  • Anything where "eventually correct" beats "instantly approximate" — file transfers, financial messages, and configuration updates all fall firmly on TCP's side of the line.

The real lesson isn't "UDP good, TCP bad" — it's that reliability and ordering are features with a cost, and that cost (head-of-line blocking) is sometimes larger than the problem they solve. WebRTC's design is a good template for the general pattern: pick the loosest guarantees your data can tolerate by default, and layer stronger guarantees back on only for the parts of the system that genuinely need them.

Key takeaways

  • TCP guarantees reliable, ordered delivery and manages congestion, but a single lost packet stalls everything behind it (head-of-line blocking).
  • UDP guarantees almost nothing — datagrams may be lost, duplicated, or reordered — but one lost datagram never blocks any other.
  • For live audio/video, a late packet is often worse than a lost one: the moment it described has already passed, so retransmitting it just delays everything else.
  • WebRTC runs media over RTP/RTCP on UDP and leans on loss-tolerant codecs, while its data channels use SCTP over UDP to add reliability and ordering back in only when needed.
  • Choose TCP-like guarantees whenever correctness matters more than the last few hundred milliseconds — authoritative game state and chat messages included.
2026 — Built by Arpit Mishra