We maken Tailscale sneller
Als je Tailscale volgt, weet je dat we in essentie een groep geeks zijn die veel waarde hecht aan internetconnectiviteit. Een onderwerp waar we graag over praten is NAT Traversal. Dat is een van de kernwaarden van Tailscale: we hebben NAT getemd. Niet elk netwerk is vriendelijk, maar Tailscale kan in een breed scala aan omstandigheden toch een pad vinden. Dat is echter niet het enige belangrijke aspect van een internetprotocol; het dataplane moet ook performant zijn.
In de loop der jaren hebben we geïnvesteerd in het versnellen van Tailscale. We begonnen met het verhogen van de TCP-doorvoer op Linux-apparaten. Daarna boekten we significante doorbraken in wireguard-go om op bare metal de 10 Gb/s te overschrijden. Later maakten we gebruik van segmentation offloads om de doorvoer voor UDP-gebaseerde applicaties met meer dan 4x te verhogen. Naast deze verbeteringen aan ons dataplane hebben we primitieven gebouwd zoals Tailscale Peer Relays, die de netwerkprestaties in lastige omstandigheden kunnen verbeteren.
Al dit heeft Tailscale praktisch gemaakt voor prestatiegevoelige workloads. Dit betekent dat je Tailscale kunt gebruiken voor continue integratie (CI), agentische workflows, remote development-omgevingen, robotische edge-apparaten, zware data- en telemetrie-workloads, en meer. Tailscale helpt deze apparaten om verbinding te maken onder uiteenlopende netwerkomstandigheden.
Hoewel we vinden dat Tailscale snel is, geloven we dat het nog sneller kan. In dit artikel leggen we uit hoe we de doorvoer voor app-connectoren, subnet-routers en exit-nodes verhogen met multi-queue-technologie (beschikbaar in de tweede helft van 2026). We geven een voorproefje van verbeteringen in doorvoer en geheugenverbruik die we implementeren in toekomstige stabiele client-releases, en we bespreken prestatie-tooling die we willen ontwikkelen voor onze klanten.
Minder geheugenverbruik voor kleine pakketten
De meeste netwerkpakketten zijn klein, ongeveer 1 KiB. Om echter de meest efficiënte doorvoertools van Linux te gebruiken, zoals Generic Receive Offload (GRO), moet Tailscale klaarstaan om in één keer 64 KiB aan verkeer te accepteren. Het is vergelijkbaar met containervervoer: de havens, schepen en vrachtwagens zijn gebouwd voor één specifieke containermaat, ongeacht hoe vol deze is.
Tailscale moet deze containers uitpakken — elk pakket wordt afzonderlijk ontsleuteld en afgeleverd. De wireguard-go-implementatie, die de basis vormt voor de cryptografie en netwerkessentiële functies van Tailscale, biedt slechts één buffergrootte van 64 KiB om in uit te pakken. Hierdoor wordt een pakket van 1 KiB elke keer in een eigen buffer van 64 KiB gekopieerd. Dit is een uitstekend doel voor optimalisatie.
Op Linux en Android laat Tailscale deze pakketten nu op de plek landen waar ze zijn aangekomen. In plaats van ze naar een nieuwe locatie te kopiëren, identificeert het systeem waar elk pakket begint en eindigt binnen de enkele grote leesbeurt. Kleine pakketten blijven klein in het geheugen, velen delen één allocatie en er wordt minder tijd besteed aan kopiëren. Dit heeft in veel netwerkconfiguraties geleid tot een snelheidswinst van ongeveer 5%.
daarnaast hebben we de pakketwachtrijen (packet queues) — de lijnen waarin pakketten wachten tussen verschillende fasen van de pipeline — verkort. Deze wachtrijen zijn bedoeld om pieken in het verkeer op te vangen. Tests toonden aan dat het grootste deel van de diepte onbenut bleef, terwijl kortere wachtrijen zorgden voor minder wachttijd en minder geheugenverbruik.
De vrijgekomen geheugenruimte hebben we toegewezen aan enkele van de zwaarst belaste nodes: subnet-routers en app-connectoren.
Multi-queue voor subnet-routers, app-connectoren en exit-nodes
Subnet-routers kunnen per tailnet sterk verschillen. Voor iemand met een klein homelab-netwerk kan een subnet-router eenvoudig een kleine set 192.168.x.y non-Tailscale-apparaten afhandelen. Een subnet-router die een cloud-implementatie met honderden peers ondersteunt, zal aanzienlijk meer verkeer verwerken.
Tot voor kort verwerkten subnet-routers, app-connectoren en exit-nodes pakketten voor meerdere onafhankelijke streams in één geordende, single-thread pipeline. Dit betekende dat één enkele 'rijstrook' werd gedeeld door veel verbindingen, omdat een ontvangende applicatie zijn eigen pakketten nooit in de verkeerde volgorde mag ontvangen.
Door het verminderen van ons geheugenverbruik hadden we de capaciteit om een multi-queue-systeem te implementeren: meerdere rijstroken in plaats van één, geschaald naar de resources van de machine in plaats van het aantal peers. Elke stream pakketten krijgt een eigen rijstrook en blijft daar, terwijl de rijstroken parallel lopen. Hierdoor kan het werk worden verdeeld over meerdere CPU-cores.
Dit resulteert in een hogere totale capaciteit en een lagere vertraging tussen het ontvangen en doorsturen van pakketten voor subnet-routers en app-connectoren. Hardware die je al hebt, wordt efficiënter gebruikt. App-connectoren en exit-nodes, die doorgaans veel gebruikers met kortstondige verbindingen bedienen, merken een bijzonder merkbare boost.
"Dit vertaalt zich in een lagere latentie, in essentie een snellere verwerking van gegevens vanaf het moment dat we ze van de lijn lezen tot het moment dat we ze naar het OS sturen," aldus Alex Valiushko, member of technical staff bij Tailscale.
Doorvoersnelheid verbeteren met writev
Door gebruik te maken van de writev-mogelijkheden van Linux in de Tailscale-client, kan Tailscale meerdere stukken pakketgegevens in één operatie naar de Linux-kernel doorgeven, in plaats van deze stukken eerst te moeten kopiëren en combineren. De 'v' in writev staat voor "vector": Tailscale kan afzonderlijke stukken data beschrijven die verplaatst moeten worden, zonder ze fysiek te verplaatsen. Dit betekent minder kopieën van pakketgegevens in het geheugen, minder schrijfoperaties en een hogere doorvoer.
Snellere opstarttijd met netmap-caching
De bovengenoemde versnellingen zijn vooralsnog alleen beschikbaar op Linux en, waar van toepassing, Android-systemen. We hebben echter ook gewerkt aan functies die voor andere systemen gelden. Tailscale-clients zullen binnenkort netmap-caching kunnen gebruiken om in veel omstandigheden sneller op te starten.
Een machine die verbinding maakt met Tailscale begint meestal met het verbinden met het control plane van Tailscale, wat op een typisch netwerk ongeveer 100 milliseconden duurt. De machine authenticeert en ontvangt een "netwerkmap" (netmap) waarin staat welke apparaten hij kan bereiken en hoe. Dit opstartproces zou snel, bijna onmiddellijk, moeten aanvoelen, en met een goede netwerkverbinding is dat meestal ook zo.
Maar bij slecht vliegtuig-wifi, in een hotel met agressieve filtering of andere matige connectiviteit, kan het lang duren voordat de machine het control plane bereikt — en soms lukt dat helemaal niet. Vaak is het niet duidelijk waar het probleem ligt, maar het effect is dat je andere apparaten niet kunt bereiken. Zelfs onder ideale omstandigheden kan 100 milliseconden opstartlatentie te veel zijn voor sommige prestatiegevoelige workloads.
Netmap-caching helpt machines verbinding te maken wanneer het control plane niet snel bereikbaar is. Wanneer dit is ingeschakeld, slaat elk apparaat op je tailnet een kopie van de netmap op de schijf op. Bij het opstarten kan een apparaat deze gecachte kopie gebruiken om verbindingen met andere apparaten in het tailnet tot stand te brengen, totdat het in contact kan komen met het control plane voor de nieuwste informatie. (Deze verbindingen worden direct tussen de apparaten onderhandeld; Tailscale ziet, zoals gebruikelijk, geen van het verkeer).
"Slechte netwerkomstandigheden — dat is echt de ruimte waar mensen veel baat kunnen hebben bij netmap-caching," zegt Claus Lensbøl, member of technical staff. "Een device-client zegt dan: 'Weet je wat? We hebben nog niet met control gesproken. Dat gebeurt waarschijnlijk zo. In de tussentijd kunnen we alvast iets gaan doen.'"
Er zijn enkele beperkingen:
- Caching werkt alleen als het apparaat eerder minstens één keer verbinding heeft gemaakt met het tailnet om een netwerkmap op te halen.
- Netmap-caching vereist dat het apparaat over persistente schijfruimte beschikt.
We hebben zorgvuldig gewerkt om onnodige schrijfacties naar de schijf te minimaliseren, maar in sommige gevallen wil je dit wellicht niet inschakelen. Bij uitzonderlijk grote tailnets kan het bijwerken van een cache veel schijfverkeer vereisen. Evenzo kunnen apparaten die gebruikmaken van langzame of slijtagegevoelige opslag, zoals SD-kaarten, ervoor kiezen netmap-caching uit te schakelen.
Voor de meeste apparaten op de meeste tailnets kan deze functie echter merkbaar versnellen hoe snel apparaten bij het opstarten contact met elkaar maken. We hebben gezien dat tailnets met een slechte bereikbaarheid van het control plane bij een "warme" cache-start één tot twee ordes van grootte sneller data versturen dan bij een "koude" start. Voor apparaten met variabele opstartlatentie, of die ver verwijderd zijn van een DERP-server of het control plane, zijn de voordelen bijzonder tastbaar.
Wanneer deze verbeteringen beschikbaar zijn
- Geheugenreductie via bufferwijzigingen (Linux/Android): Verwacht in client v1.104.
- Multi-queue voor subnet-routers en app-connectoren: Gepland voor een release na v1.104.
- Doorvoerwinsten (Linux/Android): Gedeeltelijk geïmplementeerd in het voorjaar van 2026; de volledige benutting van de extra geheugen- en doorvoersnelheid is gepland voor een release na v1.104.
- Netmap-caching: Beschikbaar als feature flag in de huidige Tailscale-client; verwacht standaard aanwezig in v1.104 na verdere tests. Mobiele clients krijgen deze functie naar verwachting in een release na v1.104.
Prestaties blijven lastig te diagnosticeren en testen
Hoewel we geloven dat Tailscale snel is, zouden gebruikers daar niet simpelweg op ons moeten vertrouwen. Daarom onderzoeken we een Tailscale-bewuste monitoring- en testtoolkit. We willen onze klanten de tools geven die ze nodig hebben om hun netwerkconfiguratie te testen, diagnosticeren en begrijpen op een manier die "Tailscale-native" is.
Dit zijn de hiaten die we zien in moderne prestatietests:
- Distributiebelasting: De meeste prestatie-tooling is point-to-point en vereist dat je op elk eindpunt iets installeert.
- Starre workflows: Het is vrij eenvoudig om de verkeerde test uit te voeren, de verkeerde output te krijgen en een probleem na te jagen dat er niet is.
- Protocolondersteuning: Veel tools ondersteunen geen nieuwere protocollen, zoals QUIC en HTTP/3.
- Tailscale-bewustzijn: Algemene tooling is niet Tailscale-native. Het kan niet aangeven of een verbinding DERP of direct gebruikt, of een peer relay zou kunnen helpen, of hoe het verbindingspad in de loop van de tijd verandert.
Bestaande tooling begrijpt geen Tailscale-native paden en statussen. Daarom onderzoeken we tooling die dat wel doet.
Groetjes,