Mayak Blog

What MTU to set for WireGuard, and why 1420 is not right for everyone

MTU is the one tunnel setting that breaks a connection in the way that looks healthy. The handshake passes, the badge says “connected”, light pages open — and heavy ones hang forever. Below: where 1420 and 1360 come from, how to measure your own limit in a minute, and why AmneziaWG needs a few more bytes subtracted from that number. Every example is our own measurement on live links, including one mistake we made on them.

The short answer: where to start

If you have no time for the reasoning, here are the working numbers. They hold for the vast majority of home and mobile networks:

  • 1420 — plain WireGuard, one tunnel, a link that carries the full 1500 bytes. This is also what wg-quick uses by default.
  • 1420 minus S4 — AmneziaWG, when the profile sets S4. Why exactly that — a section of its own below.
  • 1360 — when traffic passes through two tunnels in a row.
  • 1280 — the safe fallback: it is the smallest packet every IPv6 network is required to carry (RFC 8200). You lose a little throughput, but you never get hanging pages.

The rest of this article is where those numbers come from, and what to do when none of them fits.

How many bytes the wrapping costs

MTU is the largest packet a network agrees to carry whole, without cutting it up. On an ordinary wired or Wi-Fi segment that is 1500 bytes. A tunnel wraps your packet in an envelope of its own, and the envelope takes room too — so less than 1500 is left inside. The arithmetic is exact, down to the byte:

  • outer IP header — 20 bytes for IPv4, 40 for IPv6;
  • UDP header — 8 bytes;
  • WireGuard’s own header plus the authentication tag — 32 bytes.

That is 60 bytes over IPv4 and 80 over IPv6. Hence the numbers: on a 1500-byte link, 1440 fits inside with an IPv4 outer header and 1420 with an IPv6 one. 1420 is the default precisely because it fits both — which address family ends up on the outside is decided by the network, not by you.

An important consequence: 1420 is correct only as long as the link really carries a full 1500. PPPoE connections do not (they carry 1492), nor do some mobile networks, nor any case where your tunnel runs inside another tunnel.

What a wrong MTU looks like

The failure has a very distinctive signature, and you can recognise it before measuring anything:

  • the connection comes up, the app says “connected”;
  • small requests work: a plain page opens, ping replies;
  • but heavy pages hang, a download stalls after the first kilobytes, video never starts.

The reason is that handshake and small-request packets are small — they always fit. Full-size data packets no longer fit into the link, and an intermediate hop drops them. It is supposed to send back a “packet too big” message, which would make the sender shrink its packets by itself, but those messages are often filtered out along the way — and then the sender never learns about the loss and simply retransmits. This state is known as an MTU black hole.

If the picture is different — the tunnel never comes up, or drops after a few seconds — it is almost certainly not MTU. That case is covered in “Connected” but nothing loads.

Measuring your own limit in a minute

There is no need to guess: the size your link carries can be measured with a standard ping that forbids fragmentation. Same idea everywhere, different flags:

  • Windows: ping -f -l 1392 1.1.1.1
  • Linux: ping -M do -s 1392 1.1.1.1
  • macOS: ping -D -s 1392 1.1.1.1

Adjust the number after -l or -s until you find the largest one that still gets a reply. Add 28 to it — the IP and ICMP headers, which are not counted in that size — and you have your link MTU.

Here is a live run from our own machine, exactly two commands:

  • -s 1392 — reply in 96.7 ms;
  • -s 1393 — message too long, mtu=1420.

1392 + 28 = 1420 — and the system named that number in the error text itself. Subtract 60 from the measured link MTU (or 80, if the outer header may be IPv6) and you have the tunnel MTU.

⚠️ Measure from the connection you will actually use: home Wi-Fi, mobile data and a café hotspot have different limits. And note that some networks do not answer ping at all — then pick another destination rather than concluding that the packet did not fit.

Why AmneziaWG needs different maths

AmneziaWG is WireGuard with the outward shape of its packets made configurable. One profile parameter, S4, adds a few extra bytes to every transport packet. Those bytes are missing from the arithmetic above, which is exactly why the usual calculation gives the wrong answer on AmneziaWG:

size on the wire = MTU + 32 + S4 + 8 + 20 (with an IPv4 outer header).

Our live case, 7 August 2026. A link with S4=15 and MTU 1420: a full-size packet weighed 1420 + 32 + 15 + 8 + 20 = 1495 bytes on the wire. The tunnel came up; data did not flow. Another link, with S4=0, produced 1480 bytes from the very same network and worked. The difference between “works” and “does not work” was fifteen bytes of padding.

On 21 August we re-measured this on a clean node and got the numbers that settle it: exactly 1500 bytes leave the box and not one byte more, while links with S4=23 and S4=27 at MTU 1420 emit packets of 1503 and 1507 bytes. With a large S4, the standard 1420 is not merely risky — it is guaranteed to be over the limit.

Hence the rule: subtract S4, and not S1, S2 or S3 — those add bytes only to handshake packets, which are small anyway. And subtract it from the MTU rather than lowering S4: S4 has to match on both ends, and changing it on a live tunnel kills the flow — we tried, the tunnel came back up and the traffic stopped. MTU is one-sided, so it is safe to change. What S4 actually does, and which other config fields have to match the server, is in every field of an AmneziaWG config explained.

Both ends of the tunnel have an MTU

This is the part we tripped over ourselves, and it is not obvious. The MTU on your side only limits what leaves you. The size of what arrives is set by the interface on the server. So the right number in the client .conf alone fixes exactly half the problem: requests go out, large replies still do not get through.

In our case the client was handed a computed 1408 while the node’s interface came back up at a bare 1420 after every configuration rebuild — the same twelve S4 bytes apart. From the user’s side the symptom was the familiar one: connected, pages hang. If you run your own server, check the mtu of the interface on it, not just the client config.

Two tunnels in a row — another 60 bytes off

When traffic goes through two tunnels, one inside the other, the envelope is applied twice: the same 60 bytes come off again. That is where 1360 comes from. It is a common situation beyond services like ours — you get two tunnels if you run your own WireGuard over a corporate network that is itself a tunnel.

The rule is simple: every extra layer of wrapping costs 60 bytes (80 if that layer runs over IPv6).

What we run, and how it turned out

Our own history with this number took two months and is worth telling in full — not least because it contains a mistake of ours.

June. On one node, large packets would not pass at MTU 1380: the tunnel came up, sites did not load. We set 1280 and it worked. For good measure we also switched on a safety net that forcibly shrinks TCP segments.

Late July. The owner of the service asked a fair question: why hold the speed down “just in case” when nothing is broken? Both safety nets came off at once and we set the standard 1420 and 1360. We judged the result by facts: 11.8 GB of traffic in a day across live links and not a single complaint about hanging pages.

August. The S4 case above surfaced, and the “subtract S4” rule landed in three places at once: in the client config we hand out, in the node provisioning template, and in the configuration rebuild.

🔴 And now the mistake. The first write-up of that August case explained it like this: “his home line is PPPoE with MTU 1492, so 1495 did not fit.” The explanation looked flawless and was invented: two weeks later it turned out his home line is fibre with an honest 1500. The symptom was real, the measurement was real — the stated cause was not. We never did find out which hop was cutting it; the “subtract S4” rule does not depend on that and is confirmed from the other side, by those 1503 and 1507 bytes.

The lesson is more useful than the number itself: “a fitting explanation” and “a verified cause” are different things. MTU is precisely the area where plausible explanations are plentiful and a measurement takes one command.

Short version: start at 1420, subtract S4 if you have one, and confirm by measuring rather than by eye. The “connected, but heavy pages hang” symptom is almost always MTU — and almost never link speed.

Try Mayak

We work the MTU out on the service side and hand it to the app ready — together with the parameters of the link you connected to. Our own servers in the Netherlands, Poland and Russia, and an honest label showing which route you are on. 7 days free once you confirm your email, no card required.

The account is created right in the app. A confirmed email opens the access — 7 free days.