RFC 1323
SUPERSEDEDTCP Extensions for High Performance
V. Jacobson, R. Braden, D. Borman · May 1992 · original status: Proposed Standard · current status: Obsoleted (Proposed Standard, historic interest)
obsoleted by: RFC 7323
Obsoleted by RFC 7323 (2014), which kept the mechanisms and tightened the rules from 22 years of deployment experience. Lessons teach RFC 7323 behaviour and flag where 1323 differed.
This module teaches BOTH the historical problem and today's rules
This document
- RFC 1323 §2 — Window Scale option
- RFC 1323 §3 — Timestamps option (RTTM)
- RFC 1323 §4 — PAWS
Where the current rules live
- RFC 7323 §2 — Window Scale (current rules, incl. shift cap 14)
- RFC 7323 §3–4 — Timestamps and RTTM clarifications
- RFC 7323 §5 — PAWS
TCP Extensions for High Performance (window scaling & timestamps)
New to these ideas? Switch to the beginner level for a from-zero concept primer.
The problem this document answered
The sender may keep at most one window's worth of unacknowledged data in flight, then must wait an RTT. That makes throughput ≤ window / RTT — the bandwidth-delay product limit. With a 64 KB ceiling and 200 ms RTT you cannot exceed ~2.6 Mbit/s no matter how fast the link. RFC 1323 added Window Scale (a shift applied to every later window field), Timestamps (accurate RTT measurement), and PAWS.
Historical context
RFC 1323 (May 1992, Jacobson/Braden/Borman) followed the 1988 congestion-control work as the second wave of 'make TCP work on modern networks'. Deployment was slow and painful: buggy middleboxes stripped or mangled the options for years, which is why RFC 7323 (2014) exists — same mechanisms, rules tightened by two decades of operational scars.
Current practice
RFC 7323 is the current specification and both options are near-universal: virtually every SYN you capture today offers Window Scale and Timestamps. Shift is capped at 14. Linux commonly offers shift 7; the negotiated value is per-direction and applies to every segment AFTER the SYNs.
Interactive laboratory
📡 Bandwidth-delay product — why 64 KB stopped being enough
The WINDOW is the bottleneck, not the link: the sender can only have 65.5 KB in flight, then must wait a full 200 ms round trip. You are using 0.3% of a 1000 Mbit/s link. Raise the window-scale shift and watch this change.
Throughput ≤ window ÷ RTT — the rule behind RFC 7323. The shift is negotiated once on the SYNs and applies to every window field afterwards; it allocates no memory, it only lets a big buffer be expressed in 16 bits.
Watch it on the wire
A 200 ms satellite-class path and 256 KB of buffer on both sides — but no window scaling, so the 16-bit window field caps everything at 65,535 bytes in flight. Watch the sender idle between window-fulls.
Identical path and buffers, but both SYNs offer Window Scale (shift 3). The window field now means ×8, the full 256 KB is usable, and the same file finishes in a fraction of the time.
The client offers shift 2 (×4), the server shift 7 (×128). Both are honoured — each side scales what IT receives. Inspect the two SYNs and the window fields that follow.
The client offers Window Scale; the (older) server's SYN-ACK carries none. Per RFC 7323 §2.2 the offer is void for BOTH directions — watch the connection fall back to raw 16-bit windows.
Every segment carries TSval/TSecr. Each returning ACK echoes the timestamp of the data it acknowledges, giving the sender an exact RTT sample — the raw material for the retransmission timer.
Compare correct vs historic / naive behaviour
Original RFC vs current standard
Specification status
- Original behaviour
- RFC 1323 (1992) defined Window Scale, Timestamps and PAWS as a Proposed Standard.
- Current behaviour
- RFC 7323 (2014) obsoletes it — same three mechanisms, clarified rules.
- What changed
- No new mechanisms; tightened edge-case handling and text clarity after 22 years of deployment.
- Why it changed
- Interoperability scars: middleboxes stripping options, ambiguous timestamp rules, under-specified corner cases.
📷 In a capture: Identical on the wire — kind 3 and kind 8 options. You cannot tell 1323 from 7323 in a capture; only behaviour in corner cases differs.
Maximum scale shift
- Original behaviour
- RFC 1323 permitted shift values up to 14, with looser guidance on handling larger offers.
- Current behaviour
- RFC 7323 §2.2: shift MUST NOT exceed 14; a larger received value is treated as 14 with an error logged.
- What changed
- Explicit cap and explicit handling of illegal values.
- Why it changed
- 1 GB (65,535 × 2¹⁴) already exceeds practical buffers, and unbounded shifts risk sequence-space confusion.
📷 In a capture: Real SYNs show shifts of 0–14 (commonly 7); a shift > 14 marks a broken or hostile stack.
Timestamp echo rules
- Original behaviour
- RFC 1323 specified TSecr echoing with corner cases left partly to implementers.
- Current behaviour
- RFC 7323 §3–4 spells out precisely which TSval to echo, including during holes and after retransmissions.
- What changed
- Ambiguities resolved into explicit rules.
- Why it changed
- Divergent implementations produced inconsistent RTT estimates and PAWS behaviour.
📷 In a capture: Every established-connection segment carries TSval/TSecr; a TSecr that never advances suggests a stale or broken echo.
Common misconceptions
- ✗“Window scaling makes the buffer bigger” — it doesn't allocate a byte of memory; it only lets an existing large buffer be EXPRESSED in a 16-bit field.
- ✗“The scale factor is negotiated to a common value” — like MSS, each direction has its own shift; the client's and server's can differ (see the asymmetric scenario).
- ✗“Scaling applies to the SYN's window too” — it does not. SYN and SYN-ACK windows are always raw, because the shift isn't agreed until both SYNs are seen.
- ✗“If I offer scaling I get scaling” — only if the PEER also offers it. One silent SYN-ACK voids it for both directions (RFC 7323 §2.2).
- ✗“Timestamps are just for statistics” — they feed the retransmission timer and PAWS; without them, an RTT sample after a retransmission is ambiguous.
Glossary terms used here
Knowledge check
1/4 · A 1 Gbit/s link with 200 ms RTT, no window scaling, 64 KB windows. What throughput can a single TCP connection reach?
2/4 · A client's SYN offers Window Scale 7. The server's SYN-ACK carries no Window Scale option. What happens?
3/4 · Window Scale 3 was negotiated. A data segment's window field reads 32,768. How much room is the sender of that segment actually advertising?
4/4 · Troubleshoot: a 10 Gbit/s intercontinental transfer plateaus at ~2.6 Mbit/s. The capture shows every window field at exactly 65,535. Diagnosis?