Emergency server help: get in touch

VPN MTU Fragmentation: Fixes for Slow VPN Throughput

Find the real path MTU with ping and tracepath, spot ICMP black holes and PMTUD failures, set the right MTU and MSS clamping on WireGuard, OpenVPN and IPsec tunnels on Linux and pfSense, and measure the throughput gain with iperf3.

Published Updated 5 min read

A VPN that pings fine but crawls when copying files, hangs on some websites and drops SSH sessions mid-command is almost always an MTU problem. Every tunnel adds header bytes, so a 1500-byte packet from a client no longer fits inside a 1500-byte WAN frame; it must be fragmented, or the sender must be told to shrink it. When a firewall along the path silently drops the ICMP message that carries that instruction, large packets vanish while small ones pass, which is exactly the symptom pattern above. This guide gives a repeatable way to find the working size and enforce it on Linux hosts and pfSense or OPNsense firewalls.

Short answer: Measure the largest packet that crosses the tunnel with ping -M do -s <size> from a client, add 28 bytes for the IP and ICMP headers to get the path MTU, then set the tunnel interface MTU to that value and clamp TCP MSS to MTU minus 40 on the firewall. For WireGuard over a 1500-byte link 1420 is the safe default, for OpenVPN 1400 with mssfix 1360, and for IPsec enable MSS clamping at 1400 on pfSense under VPN » IPsec » Advanced Settings.

Confirm the symptom is MTU

Small ICMP echoes succeed but large transfers stall. Test with the don’t-fragment bit set, starting large and stepping down until replies return:

ping -M do -s 1472 -c 2 10.20.0.1
ping -M do -s 1392 -c 2 10.20.0.1
tracepath 10.20.0.1

On Windows the equivalent is ping -f -l 1472 10.20.0.1. The first size that works, plus 28, is the effective path MTU across the tunnel; tracepath reports the same figure hop by hop. If 1472 fails on the plain WAN path without any VPN, the ISP connection itself has a reduced MTU, common on PPPoE and some LTE links, and the tunnel must be sized below that.

Understand the overhead

WireGuard adds 60 bytes on IPv4 and 80 on IPv6, so 1500 minus 80 gives the widely used 1420. OpenVPN in UDP mode adds roughly 40 to 70 bytes depending on cipher and authentication, so 1400 leaves margin. IPsec ESP in tunnel mode with NAT traversal adds between 50 and 80 bytes. Stacking tunnels, such as WireGuard inside a PPPoE link with an MTU of 1492, compounds the loss and you must subtract both. Getting this wrong by a few bytes produces intermittent failures that look like packet loss.

Fix it on Linux hosts

Set the tunnel MTU explicitly. For WireGuard add MTU = 1420 to the [Interface] section of /etc/wireguard/wg0.conf and restart with wg-quick down wg0 && wg-quick up wg0. For OpenVPN add tun-mtu 1400 and mssfix 1360 to both server and client configurations. Confirm with ip link show wg0. Where the host also routes for others, clamp MSS so TCP sessions negotiate a fitting segment size regardless of PMTUD:

iptables -t mangle -A FORWARD -o wg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
nft add rule inet filter forward oifname "wg0" tcp flags syn tcp option maxseg size set rt mtu

Use whichever firewall stack the host runs; both rules rewrite the MSS in the SYN to match the outgoing interface MTU. Also make sure the host does not block inbound ICMP type 3 code 4 (fragmentation needed), since PMTUD depends on it; a rule that drops all ICMP is a classic self-inflicted black hole.

Fix it on pfSense and OPNsense

On pfSense, set the MTU field on the assigned WireGuard or OpenVPN interface under Interfaces, and set MSS on the same page to MTU minus 40; the firewall then clamps TCP for you. For IPsec, VPN » IPsec » Advanced Settings has an Enable MSS clamping option with a value field, and 1400 works for almost every deployment. On OPNsense the equivalent MTU and MSS fields sit on each interface page, and VPN » IPsec » Advanced offers the same clamping toggle.

If the WAN itself runs PPPoE, set the WAN MTU to 1492 and let the tunnels inherit lower values. Apply and let existing states expire, or reset states under Diagnostics » States, because open TCP sessions keep their negotiated MSS until they close.

Verify the gain

Run a bandwidth test across the tunnel before and after with iperf3, which is available in both firewall package repositories and every Linux distribution:

iperf3 -s
iperf3 -c 10.20.0.5 -t 20 -P 4
iperf3 -c 10.20.0.5 -t 20 -P 4 -R

A tunnel suffering fragmentation typically shows throughput a fraction of the line rate with retransmissions in the summary; after clamping, both directions should approach the slower WAN’s capacity minus encryption overhead. Confirm with ping -M do -s 1392 that packets at the new size pass, and watch ip -s link show wg0 on Linux for errors or drops climbing. The common pitfall is fixing MSS on the firewall while a Windows client has a stale, larger MTU cached on its own adapter; check with netsh interface ipv4 show subinterfaces and reset it if needed. For the tunnel configuration itself see Set up a site-to-site WireGuard VPN between pfSense and OPNsense.

VPN MTU fragmentation at a glance

VPN MTU Fragmentation summary card: Measure the largest packet that crosses the tunnel with ping -M do -s <size> from a client, add 28 bytes for the IP and…
In short: Measure the largest packet that crosses the tunnel with ping -M do -s <size> from a client, add 28 bytes for the IP and ICMP headers to get the path MTU, then set the tunnel interface MTU to that value and clamp TCP MSS to MTU minus 40 on the firewall.

Official documentation: AlmaLinux wiki, Linux man pages.

Related guides: Install OPNsense 26.7 and set up basic firewall and NAT rules · Configure VLANs on pfSense with a managed switch · Install pfSense CE 2.9 step by step with the network installer and ZFS.

Frequently asked questions

Does MSS clamping also fix UDP traffic over a VPN?

No. MSS is a TCP option, so clamping only helps TCP. UDP applications such as VoIP or DNS with large responses rely on the tunnel MTU being correct and on PMTUD working, which is why the interface MTU must be set as well.

How long does it take for an MTU change to take effect?

The interface change is immediate, but TCP sessions already open keep their old segment size. Allow a few minutes for sessions to cycle, or reset firewall states, before re-testing throughput.

Can I undo an MTU or MSS change if it makes things worse?

Yes. Clear the MTU and MSS fields on the interface or remove the clamp rule, restart the tunnel, and the defaults return; nothing persists beyond the configuration you edited.

Free website test

Is your website set up right?

Check SSL, security headers, redirects, robots.txt, sitemap, llms.txt and security.txt in one test. It takes about 30 seconds.