SubnetLayerRFCs

RFC 879

HISTORIC · IDEAS LIVE ON

The TCP Maximum Segment Size and Related Topics

Jon Postel (ISI) · November 1983 · original status: Unknown (pre-standards-track memo) · current status: Historic

obsoleted by: RFC 7805, RFC 9293 · updated by: RFC 6691

Historic (RFC 7805) and formally obsoleted by RFC 9293, with RFC 6691 correcting how options interact with the advertised value. The core rule — MSS is payload capacity, announced not negotiated — is unchanged; the defaults and option arithmetic are where old and new differ.

This module teaches BOTH the historical problem and today's rules

This document

  • RFC 879 §1–3 — MSS definition; MSS counts data octets only
  • RFC 879 §7 — the default of 536 and the 576-octet IP datagram rule
  • RFC 879 §11–13 — MSS vs MTU relationships

Where the current rules live

  • RFC 9293 §3.7.1 — MSS communication and effective send MSS
  • RFC 6691 — MSS excludes IP/TCP options from the advertised value

The TCP Maximum Segment Size

New to these ideas? Switch to the beginner level for a from-zero concept primer.

The problem this document answered

MSS is the largest TCP payload a host is willing to receive per segment — payload only, excluding headers. Each side announces its own value on its SYN; each sender obeys the other side's. Confusing MSS with MTU (or assuming it's negotiated to one shared value) causes real misconfigurations to this day.

Historical context

RFC 879 (November 1983) fixed early confusion about the default of 536 (from the 576-octet IP minimum-reassembly rule) and the MSS/MTU relationship. Reclassified Historic by RFC 7805 and formally absorbed into RFC 9293 §3.7.1, with RFC 6691 refining option accounting.

Current practice

Every stack announces MSS on SYN/SYN-ACK (1460 is the Ethernet-typical value). Defaults without the option: 536 (IPv4) / 1220 (IPv6). Middleboxes routinely clamp MSS on the fly — visible as a SYN leaving with one value and arriving with a smaller one.

Interactive laboratory

🧮 MSS laboratory — do Postel's arithmetic yourself

path payload budget
1460 B
1500 − 20 − 20
payload per segment
1460 B
TCP segments
10
IP packet @ advertised MSS
1500 B
IP fragmentation?
no
header overhead
3.6%
10 × 54 B (incl. Ethernet)
total bytes on wire
15,140

Per RFC 6691: options are charged per-segment, never pre-subtracted from the advertised MSS. Defaults with no MSS option: 536 (IPv4) / 1220 (IPv6).

Watch it on the wire

RFC 879 · Asymmetric MSS announcements

Client announces MSS 1460, the constrained server announces 536. Each direction obeys the OTHER side's number — watch 1200 bytes travel as 536+536+128 one way and as a single segment the other.

RFC 879 · The missing MSS option

The client's SYN carries NO MSS option — so the server must assume the ancient default of 536 bytes and chops its 1200-byte response into 536-byte pieces, even though the client could take 1460.

RFC 879 · MSS clamped by a middlebox

The client announces MSS 1460, but a middlebox on the path rewrites the SYN's option to 536 in transit. The server obediently sends small segments — and the client never knows why. Inspect the SYN: the wire disagrees with the sender.

HTTP request and response

After the handshake, the browser sends a GET and the server answers.

Compare correct vs historic / naive behaviour

Original RFC vs current standard

Advertised MSS vs options

Original behaviour
RFC 879-era practice: derive MSS from MTU minus fixed 40-byte headers; option interaction underspecified.
Current behaviour
RFC 6691 / RFC 9293 §3.7.1: advertise based on bare headers; subtract options per-segment when actually used.
What changed
Options moved from 'maybe pre-subtracted' to explicitly charged per-segment.
Why it changed
Pre-subtracting options wastes capacity on segments that don't carry them (most data segments).

📷 In a capture: Modern: SYN advertises 1460 even when the SYN itself carries 20 bytes of options; data segments with timestamps carry 1448 payload bytes.

Default MSS

Original behaviour
RFC 879 §7: default 536, from the 576-octet IPv4 reassembly guarantee.
Current behaviour
536 for IPv4 still; 1220 for IPv6 (1280 minimum MTU − 60).
What changed
IPv6 brought a second default from its larger minimum MTU.
Why it changed
Same safety logic, new lower bound.

📷 In a capture: A SYN with no MSS option → the peer's data segments cap at 536/1220.

Common misconceptions

  • “MSS is the packet size” — it excludes 40+ bytes of IP/TCP headers; a 1460 MSS fills a 1514-byte Ethernet frame.
  • “The two sides negotiate a common MSS” — each direction independently obeys the receiver's announcement (see the asymmetric trace: 536 one way, 1460 the other).
  • “No MSS option means unlimited segments” — it means the 536/1220 defaults.
  • “A bigger MSS is always faster” — not past a smaller-MTU hop: oversized segments fragment or vanish.

Glossary terms used here

Knowledge check

1/3 · Ethernet MTU 1500, IPv4, no IP options, 20-byte TCP header. What MSS does a host typically announce?

2/3 · In the asymmetric scenario the client announced 1460 and the server 536. Which segments are capped at 536?

3/3 · Troubleshoot: small web pages load, large downloads hang forever, no RST, no errors. Classic cause?