tcp sliding window protocol

published: September 28, 2025

overview

the tcp sliding window protocol provides flow control and reliable data transfer by allowing multiple segments to be in flight while maintaining ordered delivery. the window slides forward as acknowledgments arrive, enabling efficient use of network bandwidth.

sliding window visualization

TCP Sliding Window Mechanism
Rendering diagram...

Shows how the send window moves as acknowledgments are received, with different regions for sent/acked, sent/unacked, and ready to send data.

window variables

sender variables

tl;dr

SND.UNASend UnacknowledgedOldest unacknowledged sequence number
SND.NXTSend NextNext sequence number to send
SND.WNDSend WindowSize of send window (from receiver)
SND.UPSend Urgent PointerUrgent data pointer
SND.WL1Segment sequence for last window updateUsed to validate window updates
SND.WL2Segment ack for last window updateUsed to validate window updates

receiver variables

tl;dr

RCV.NXTReceive NextNext expected sequence number
RCV.WNDReceive WindowSize of receive window
RCV.UPReceive Urgent PointerUrgent data pointer
RCV.IRSInitial Receive SequenceInitial sequence number received

window operation flow

Sliding Window Data Flow
Rendering diagram...

Sequence diagram showing how data segments and acknowledgments move the sliding window forward.

window states

send window regions

1. Data sent and acknowledged (left of SND.UNA)
   - Can be discarded from send buffer
   - No longer needed for retransmission

2. Data sent but not acknowledged (SND.UNA to SND.NXT)
   - Must keep in buffer for possible retransmission
   - Waiting for ACK from receiver

3. Data not sent but ready (SND.NXT to SND.UNA + SND.WND)
   - Can be sent immediately
   - Limited by receive window

4. Data not ready to send (beyond SND.UNA + SND.WND)
   - Must wait for window to advance
   - Blocked by flow control

receive window management

1. Data received and acknowledged (left of RCV.NXT)
   - Delivered to application
   - Can be removed from buffer

2. Data expected next (at RCV.NXT)
   - Waiting for this sequence number
   - Will trigger immediate ACK

3. Data acceptable (RCV.NXT to RCV.NXT + RCV.WND)
   - Within receive window
   - Can be buffered if out of order

4. Data not acceptable (beyond RCV.NXT + RCV.WND)
   - Outside receive window
   - Will be dropped

zero window handling

Zero Window Probe Mechanism
Rendering diagram...

Shows how TCP handles zero window situations using persist timer and window probes.

window scaling

for high-bandwidth networks, the 16-bit window field (max 65,535 bytes) is insufficient. window scaling extends this:

window scale option

tl;dr

Option Kind3
Option Length3 bytes
Shift Count0-14 (multiply window by 2^shift)
Max Window65,535 * 2^14 = 1,073,725,440 bytes (~1GB)

scaling operation

Actual Window = Window_Field_Value << Shift_Count

Example:
- Window field: 8192
- Scale factor: 7
- Actual window: 8192 << 7 = 8192 * 128 = 1,048,576 bytes (1MB)

silly window syndrome (sws)

problem

small window advertisements lead to inefficient small segments:

Silly Window Syndrome
Rendering diagram...

Shows how small window updates can lead to inefficient transmission of tiny segments.

prevention strategies

receiver side (clark’s algorithm):

  • don’t advertise small window increases
  • wait until window >= min(mss, rcvbuf/2)

sender side (nagle’s algorithm):

  • buffer small writes
  • send only when:
    • can send full mss
    • no unacked data (all acked)
    • connection closing (fin)

window update logic

valid window update conditions

// Window update is valid if:
// 1. Segment contains new data (advances sequence)
if (SEG.SEQ > SND.WL1) {
    accept_window_update();
}
// 2. Sequence matches but ACK advances
else if (SEG.SEQ == SND.WL1 && SEG.ACK > SND.WL2) {
    accept_window_update();
}
// 3. Same sequence and ACK but window increases
else if (SEG.SEQ == SND.WL1 && SEG.ACK == SND.WL2 && SEG.WND > SND.WND) {
    accept_window_update();
}

performance implications

bandwidth-delay product

optimal window size = bandwidth × round-trip time

tl;dr

Link TypeBandwidthRTTBDP (Optimal Window)
LAN (1 Gbps)125 MB/s1 ms125 KB
Cable Internet12.5 MB/s20 ms250 KB
Transcontinental125 MB/s100 ms12.5 MB
Satellite10 MB/s600 ms6 MB

window sizing guidelines

  1. too small - underutilizes bandwidth
  2. too large - causes bufferbloat
  3. optimal - keeps pipe full without queuing

implementation notes

buffer management

struct tcp_buffer {
    uint32_t base;      // SND.UNA or RCV.NXT
    uint32_t size;      // Buffer size
    uint32_t used;      // Bytes in buffer
    uint32_t window;    // Advertised window
    uint8_t* data;      // Actual buffer
};

// Send buffer regions
uint32_t acked_bytes = SND.UNA - ISS;
uint32_t unacked_bytes = SND.NXT - SND.UNA;
uint32_t usable_window = SND.UNA + SND.WND - SND.NXT;

receive buffer sizing

linux auto-tuning example:

# View current settings
sysctl net.ipv4.tcp_rmem
# min=4096 default=131072 max=6291456

# Receive buffer auto-scales between min and max
# Based on available memory and connection needs

common issues

window stalls

symptoms:

  • zero window persists
  • throughput drops to zero
  • connection appears hung

causes:

  • application not reading data
  • insufficient receive buffer
  • memory pressure

solutions:

  • increase socket buffer sizes
  • improve application read performance
  • monitor buffer utilization

window scaling problems

symptoms:

  • throughput limited despite bandwidth
  • cannot achieve expected speeds
  • works locally, fails over wan

causes:

  • middlebox interference
  • firewall stripping options
  • window scale not negotiated

debugging:

# Check if window scaling enabled
ss -tin | grep -i scale

# Verify window scale in packet capture
tcpdump -i any -nn 'tcp[tcpflags] & tcp-syn != 0'

key takeaways

  • sliding window enables efficient, reliable data transfer
  • window size determines maximum data in flight
  • flow control prevents receiver overflow
  • window scaling necessary for high-bandwidth paths
  • proper sizing critical for performance
  • zero window requires special handling

references

  • rfc 793 - original tcp specification
  • rfc 9293 - tcp specification (current)
  • rfc 7323 - tcp extensions (window scaling)
  • rfc 813 - window and acknowledgment strategy

next steps

on this page