TCP Selective Acknowledgment (SACK) is a mechanism that allows a TCP receiver to inform the sender about which segments have been received and which are missing, enabling more efficient retransmission of lost data.
Here’s a glimpse of SACK in action. Imagine a sender transmitting a stream of data segments.
Sender:
[Segment 1] [Segment 2] [Segment 3] [Segment 4] [Segment 5]
Due to network congestion, Segment 3 is lost. The receiver gets Segments 1, 2, 4, and 5. Instead of simply acknowledging the last in-order segment it received (Segment 2), which would trigger a retransmission of Segment 3 and potentially others, the receiver uses SACK.
Receiver (with SACK): It sends back an acknowledgment that includes a SACK option. This option specifies the contiguous blocks of data that have been received.
ACK(2) with SACK: [4-5]
This tells the sender: "I received up to segment 2, and I also have segments 4 and 5." The sender now knows exactly that Segment 3 is missing, without inferring it from a delayed ACK or duplicate ACKs. It can then retransmit only Segment 3.
Sender retransmits: [Segment 3]
This is a significant improvement over older TCP mechanisms where the sender might have to wait for multiple duplicate ACKs (indicating a gap) or a retransmission timer to expire. The sender’s perspective changes from "I think segment X is lost" to "I know segment X is lost."
The problem SACK solves is the inefficiency of traditional TCP retransmission strategies in the face of packet loss. Without SACK, if segment 3 is lost, the receiver might acknowledge segment 2. The sender, seeing an ACK for segment 2, assumes segment 3 is lost. However, if segment 4 also gets lost, the receiver might still acknowledge segment 2. The sender would then receive another ACK for segment 2, which doesn’t give it new information about which segment is lost beyond segment 2. It might have to wait for a retransmission timeout (RTO), which can be a long delay, or for three duplicate ACKs for segment 2 to signal a potential loss.
With SACK enabled, the receiver can report multiple non-contiguous blocks of received data. If segments 3 and 5 are lost, but 1, 2, 4, and 6 are received:
Sender:
[Segment 1] [Segment 2] [Segment 3] [Segment 4] [Segment 5] [Segment 6]
Network Loss: Segments 3 and 5.
Receiver (with SACK):
ACK(2) with SACK: [4-4], [6-6]
This clearly indicates that segments 3 and 5 are missing. The sender can then immediately retransmit only segments 3 and 5. This dramatically reduces unnecessary retransmissions and speeds up recovery.
The key levers you control with SACK are primarily at the operating system level, as it’s a TCP option negotiated during the handshake. You don’t typically "configure" SACK directly in applications, but rather ensure your operating system’s TCP stack has it enabled and tuned.
To enable SACK on Linux, you’d typically check and potentially modify /proc/sys/net/ipv4/tcp_sack. A value of 1 enables it, 0 disables it.
# Check current setting
cat /proc/sys/net/ipv4/tcp_sack
# Output: 1 (if enabled)
# Enable SACK (if not already enabled)
sudo sysctl -w net.ipv4.tcp_sack=1
On FreeBSD, you might look at net.inet.tcp.sack in sysctl.conf.
# Check current setting
sysctl net.inet.tcp.sack
# Output: net.inet.tcp.sack: 1
# Enable SACK (if not already enabled)
# Edit /etc/sysctl.conf and add/modify:
# net.inet.tcp.sack=1
# Then apply:
sudo sysctl -p
Windows also supports SACK, and it’s generally enabled by default on modern versions. You can verify its status via netsh interface tcp show global and look for "Selective Acknowledgments (SACK)".
The "magic" of SACK is that it provides the sender with explicit information about received data, not just inferred information about lost data. This allows the sender to bypass the often-slow duplicate ACK mechanism and the even slower retransmission timeout, leading to much faster recovery from packet loss. It’s a fundamental building block for TCP’s performance in lossy networks.
The next logical step after understanding SACK is exploring how TCP congestion control algorithms, like Cubic or BBR, leverage this precise loss information to make more intelligent decisions about congestion avoidance and window scaling.