What it does

Enter a link MTU (Maximum Transmission Unit) and, optionally, the encapsulation stack the traffic crosses, and the tool computes everything the MTU line controls: the inner IP MTU and the TCP MSS (Maximum Segment Size) for IPv4 and IPv6, the Ethernet frame sizes the link must accept, the underlay MTU an overlay needs to carry full 1500-byte inner packets, and the wire efficiency of this MTU against the standard 1500 and jumbo 9000 reference points. Everything is fixed RFC header arithmetic, computed locally.

The input line

Start with the MTU, then add tokens in any order: v6 (IPv6 outer header for tunnels), pppoe, gre, ipip, 6in4 (or sit), vxlan, geneve, wireguard (or wg), vlan (or dot1q), qinq, mpls or mpls2..mpls8, and +N for a custom overhead in bytes. So 1500 vxlan is the canonical overlay question, 1500 gre v6 is GRE over IPv6, 9000 vxlan vlan is a tagged jumbo underlay, 1500 mpls2 is a link carrying two labels, and 1500 +57 models a measured IPsec cost.

The one distinction that matters

Overheads sit on different sides of the MTU line, and the tool lists every layer with its side.

Encapsulations (PPPoE, GRE, IP-in-IP, 6in4, VXLAN, GENEVE, WireGuard, your custom +N) consume bytes inside the link MTU, so they shrink the inner IP MTU and the MSS: that is why a GRE tunnel on a 1500-byte link shows MTU 1476.

Multiprotocol Label Switching (MPLS) labels also spend link MTU. RFC 3032 defines the frame payload as the frame without its data link headers and trailers, 802.1Q headers included, and for a labelled packet "the Frame Payload consists of the label stack entries and the IP datagram" (RFC 3032, section 3.1). Each label stack entry is 4 octets (section 2.1), so on a link left at Ethernet's conventional 1500-byte payload the IP datagram gets 1496 bytes with one label, 1492 with two and 1488 with three; 1488 is the size section 3.2 gives for a datagram that still fits a 1500-byte link "even if as many as three labels are pushed onto its label stack". The Ethernet frame does not grow. To carry full 1500-byte IP packets, the link's MPLS MTU has to be raised by 4 bytes per label, which is RFC 3032's own example: a packet with a 1500-byte frame payload that gets one more label must be forwarded "as frame with a 1504-byte payload" (section 3).

802.1Q VLAN tags and QinQ are the true layer 2 shims: they ride in the frame header outside the payload, so the IP MTU does not move at all; the frame grows instead, which is why one VLAN tag makes a 1522-byte baby giant and why switch platforms carry frame headroom (system MTUs like 9216) rather than shrinking the IP MTU.

Path MTU Discovery: how a sender meets these numbers

The inner MTU this tool prints is the number a sender has to discover on a real path. In IPv4 Path MTU Discovery (PMTUD) the source sends datagrams with the Don't Fragment (DF) bit set and relies on Internet Control Message Protocol (ICMP) errors to learn when they are too big; a router that cannot forward one without fragmenting it "will discard them and return ICMP Destination Unreachable messages with a code meaning 'fragmentation needed and DF set'", and the source lowers its estimate (RFC 1191, section 2). The router "MUST include the MTU of that next-hop network" in that ICMP message (section 4), so the Next-Hop MTU it reports is the same kind of number this tool computes for a tunnel or a label stack. In IPv6 the message is ICMPv6 Packet Too Big: "Path MTU Discovery relies on ICMPv6 Packet Too Big (PTB) to determine the MTU of the path" (RFC 8201, section 1). MPLS keeps the mechanism working: a labelled IPv4 datagram that is too big and has DF set "MUST NOT be forwarded", and the ICMP reply carries a Next-Hop MTU equal to the effective maximum frame payload minus the label bytes (RFC 3032, section 3.4).

The common failure is a filter that drops those ICMP messages. PMTUD "fails when the appropriate ICMP messages are not received by the originating host", the packets disappear "into a PMTUD black hole", and the fault is hard to find "as pings and some interactive TCP connections to the destination host work" while bulk transfers fail with the first large packet (RFC 2923, section 2.1). RFC 8201 describes the same state in IPv6 as connections "that complete the TCP three-way handshake correctly but then hang when data is transferred" (section 1). The usual workaround for TCP is MSS clamping: tunnel endpoints lower the MSS so that the connection "automatically restricts itself to the maximum available packet size"; it does nothing for UDP or other protocols that have no MSS, and it assumes all the traffic goes through the clamping endpoints (RFC 4459, section 3.2). On Linux the iptables TCPMSS target rewrites the MSS of TCP SYN packets, usually to the outgoing interface MTU minus 40 for IPv4 or 60 for IPv6, the same subtraction behind this tool's two MSS lines, and its manual names what it works around: ISPs or servers "which block 'ICMP Fragmentation Needed' or 'ICMPv6 Packet Too Big' packets" (iptables-extensions(8), TCPMSS). Clamping hides the symptom; RFC 2923's advice stands: "Ideally, the ICMP black holes should be fixed when they are found" (section 2.1).

The numbers it uses

Every constant is protocol-fixed: IPv4 header 20 (RFC 791), IPv6 40 (RFC 8200), TCP 20 (RFC 9293), UDP 8 (RFC 768), Ethernet header 14 + FCS 4 with 20 bytes of preamble and inter-frame gap on the wire, 802.1Q tag 4 in the frame header, MPLS label stack entry 4 inside the frame payload (RFC 3032), PPPoE 8 (RFC 2516), GRE base 4 (RFC 2784), IP-in-IP and 6in4 outer-header-only (RFC 2003 / RFC 4213), VXLAN 8 + UDP + outer IP + inner Ethernet = 50 with IPv4 outer or 70 with IPv6 (RFC 7348), GENEVE the same base with variable options on top (RFC 8926), and WireGuard 60 with IPv4 outer or 80 with IPv6. IPsec ESP is deliberately not a preset: its overhead genuinely varies with mode, cipher, IV size, padding, integrity tag, and NAT-T, so pretending one number would be dishonest. Measure yours (or take it from your platform's documentation) and enter it as +N.

Worked examples

1500 alone gives MSS 1460 (IPv4) and 1440 (IPv6), a 1518-byte maximum frame, and 94.93% wire efficiency. 1500 gre gives the classic 1476 inner MTU. 1500 vxlan gives 1450 inner and answers the design question: a 1550-byte underlay carries full 1500-byte inner packets. 1500 pppoe gives the famous 1492. 1500 vlan leaves the inner MTU at 1500 and grows the frame to the 1522-byte baby giant. 1500 mpls gives 1496 inner and MSS 1456, keeps the frame at 1518, and shows that the link needs a 1504-byte payload for full 1500-byte IP packets; 1500 vlan mpls2 gives 1492 inner, a 1522-byte frame and a 1508-byte payload requirement. 9000 vxlan gives 8950 inner, the standard datacenter overlay answer. 1500 wireguard gives 1440, and 1492 wireguard (WireGuard over PPPoE) gives 1432.

Provenance

Header sizes are from the RFCs named above; the composite overheads (GRE 24, VXLAN 50/70, WireGuard 60/80, PPPoE 8) were cross-verified against multiple independent tunnel-overhead references on 2026-07-20. On 2026-10-19 the MPLS rule was corrected against RFC 3032 section 3.1: earlier versions placed labels in the frame header with the 802.1Q tags and left the IP MTU unchanged. The tool ships 25 golden vectors (set mtu-mss/2026-10-19a) pinning every classic number, RFC 3032's 1504 and 1488 among them, so any drift in the arithmetic breaks the build.

API

The same engine answers the /api/v1/mtu-mss operation of the site's HTTP API, written out field by field in the OpenAPI contract on the API page, with examples taken from the golden vectors. The contract also says whether this site serves the API.

  • Request. The input line as text, such as 1500 vlan mpls2.
  • Response. mtu, outer, layers (each with id, bytes and kind: encap, label or shim), encapTotal, labelTotal, shimTotal, innerMtu, mssV4, mssV6, frame, efficiency, underlay (present when the stack spends bytes inside the MTU), innerIsV6Only and hasVariableLayer. For 1500 vlan mpls2 the API answers innerMtu 1492, labelTotal 8, shimTotal 4, frame.maxFrame 1522 and underlay.requiredMtu 1508.
  • Errors. HTTP 400, invalid_input, with the engine's message, for example mpls label count must be 1..8 for 1500 mpls9.

Since 2026-10-19 MPLS labels are the label kind: labelTotal is new and is subtracted from the MTU, shimTotal counts 802.1Q and QinQ tags only, and underlay.requiredMtu is 1500 plus encapTotal plus labelTotal.

Sources