Negative Acknowledgments: Flow Control Through Selective Retransmission


Most developers learn about acknowledgments early: the receiver tells the sender “I got message 42,” and communication proceeds. But high-throughput streaming systems often flip this model on its head, using negative acknowledgments (NACKs) to request only what went wrong rather than confirming everything that went right.

The difference matters when you’re pushing gigabits of video, financial market data, or sensor telemetry where the cost of acknowledging every packet becomes a bottleneck in itself.

The ACK Tax

Traditional positive acknowledgment schemes like TCP’s cumulative ACK work well for general-purpose traffic. The receiver periodically tells the sender the highest sequence number it has received in order. If an ACK doesn’t arrive, the sender retransmits.

This approach guarantees reliability but introduces overhead. Every segment needs acknowledgment, and the sender must track which segments are outstanding. At scale, ACK traffic consumes bandwidth, processing cycles, and memory. For a multicast scenario where one sender serves thousands of receivers, positive ACKs create an implosion problem: everyone tries to acknowledge simultaneously, overwhelming the sender.

NACKs invert the assumption. Instead of confirming receipt, receivers only speak up when something is missing.

How NACKs Work

A NACK-based protocol assumes successful delivery by default. The sender transmits a stream of packets, each numbered sequentially. Receivers detect gaps in the sequence and send targeted requests: “I’m missing packet 5038.”

The sender responds by retransmitting only the missing packets. No acknowledgment means everything arrived. Silence is success.

This approach works particularly well in multicast and broadcast environments. A single sender can stream to many receivers without being crushed by acknowledgment traffic. Only receivers experiencing packet loss generate feedback, and that feedback is specific enough for efficient recovery.

Real-time protocols like RTP (Real-time Transport Protocol) pair NACKs with receiver-side buffering. When a gap is detected, the receiver requests retransmission while continuing to process subsequent packets. If the missing data arrives in time, it is inserted into the correct position in the stream. If it arrives too late, it may be discarded to preserve real-time constraints.

Latency and Timing Tradeoffs

NACKs introduce a new variable: detection delay. With positive ACKs, the sender learns about delivery failure when an expected acknowledgment doesn’t arrive within a timeout window. With NACKs, the sender only learns when the receiver notices the gap and sends a request.

This means receivers must monitor sequence numbers actively and decide when a gap represents loss versus out-of-order delivery. Sending a NACK too early wastes bandwidth on spurious retransmissions. Waiting too long increases recovery latency.

Many implementations use a short delay timer: if the next expected packet doesn’t arrive within a few milliseconds and subsequent packets do, assume loss and send a NACK. The timer must be tuned to network conditions. On low-latency LANs, 5ms might suffice. Over satellite links or congested WANs, 50ms may be necessary.

Selective Retransmission vs. Full Recovery

NACKs enable selective retransmission: the sender resends only the specific packets requested. This contrasts with go-back-N schemes where loss triggers retransmission of all subsequent packets, or with simple stop-and-wait approaches where the sender halts until receiving confirmation.

Selective retransmission is efficient when loss is rare and localized. If 10,000 packets are sent and packet 5038 is lost, only one retransmission is needed. The receiver continues processing packets 5039 onward while waiting for the missing piece.

But selective retransmission requires both sender and receiver to maintain state about which packets are outstanding and which gaps remain. The sender needs a retransmit buffer holding recently sent packets. The receiver needs a reordering buffer to hold out-of-sequence data.

When NACKs Fail

NACK-based protocols struggle under heavy loss. If 20% of packets are lost, NACK traffic can exceed the overhead of positive ACKs. Each loss triggers a NACK, and retransmissions may themselves be lost, generating additional NACKs.

Congestion exacerbates the problem. If the network is saturated, retransmissions compete with new data for bandwidth, and NACKs add to the load. Many NACK protocols incorporate congestion control mechanisms: exponential backoff for retransmission requests, rate limiting on NACK generation, or fallback to FEC (forward error correction) where redundant data is sent proactively rather than reactively.

NACKs also require reliable delivery of the NACK message itself. If a NACK is lost, the receiver must detect that its request was not fulfilled and send another. This is typically handled with a retry timer: if the missing packet doesn’t arrive within a threshold after sending the NACK, send it again.

Real-World Deployment

WebRTC uses NACKs extensively for video streaming. When a browser detects missing RTP packets, it sends RTCP NACK messages to request retransmission. Because video conferencing tolerates some loss but values low latency, NACKs allow quick recovery without the overhead of acknowledging every frame.

Financial market data feeds use NACKs to deliver trade and quote updates to thousands of subscribers simultaneously. A multicast stream pushes updates at line rate, and individual clients NACK when they detect gaps. The architecture scales because only clients experiencing loss generate traffic back to the source.

Reliable multicast protocols like PGM (Pragmatic General Multicast) and NORM (NACK-Oriented Reliable Multicast) build NACK mechanisms directly into the transport layer, offering reliable delivery over UDP multicast without per-receiver state at the sender.

NACKs aren’t a replacement for positive acknowledgments everywhere, but in high-throughput, low-loss, one-to-many scenarios, they turn the acknowledgment model inside out and make scaling possible.