What is SACK
SACK (Selective Acknowledgment) lets TCP acknowledge non-contiguous data — telling the sender exactly which packets arrived so only the missing ones need to be retransmitted.
What is the problem without SACK?
Standard TCP acknowledgments are cumulative: an ACK for byte 5000 means "I've received everything up to byte 5000." If the sender transmitted bytes 1–10000 and the packet containing bytes 3001–4000 was lost, the receiver can only ACK up to byte 3000 — even though bytes 4001–10000 arrived fine.
Without SACK, the sender has limited options. It can retransmit just the missing segment and hope it guessed right, or it can retransmit everything from byte 3001 onward — wasting bandwidth resending data the receiver already has. When multiple packets are lost, this gets worse quickly.
How does SACK work?
During the TCP handshake, both sides negotiate SACK support using a TCP option. Once enabled, the receiver can include SACK blocks in its ACKs — pairs of byte ranges indicating which data arrived out of order.
For example: "I've received everything up to byte 3000 (cumulative ACK), and I also have bytes 4001–7000 and 8001–10000 (SACK blocks)." The sender now knows exactly which segments are missing: 3001–4000 and 7001–8000. It retransmits only those two segments.
How do you see it in captures?
In tcpdump or Wireshark, SACK appears as a TCP option on ACK packets: sack 1 {4001:7000}. SACK-permitted appears in the SYN/SYN-ACK during the handshake.
Why it matters
SACK is enabled by default on every modern operating system and is critical for performance on lossy networks. Without it, a single burst of packet loss can trigger retransmission of large amounts of data the receiver already has, wasting bandwidth and increasing recovery time. With SACK, TCP precisely targets only the gaps.