Get started
Login
© 2024

Connection types

Tailscale connections devices within a tailnet using DERP relay servers and direct connections. In a typical scenario, two tailnet devices connect using the following sequence of events:

  1. Device A wants to connect to an application on a device B.
  2. Device A connects (if not already connected) to the DERP relay server that device B is already connected to.
  3. Device A sends the application connection request through the DERP relay server.
  4. Device A sends a request for direct connection details through the DERP relay server.
  5. Device B responds to the application connection request through the DERP relay server.
  6. Device B responds with direct connection details through the DERP relay server and starts performing NAT traversal strategies.
  7. Device A continues to perform application communication through the DERP relay server until a direct connection succeeds. If that never happens, it uses the DERP relay server the entire time the connection is active.

Direct connections vs relayed connections

Tailscale uses direct and relayed connections. All connections within a tailnet begin as a relayed connection, at which point, Tailscale attempts to establish a direct connection between the devices. If a direct connection isn't possible, the connection remains relayed.

Direct connections

A direct connection is a connection between two devices where the devices can send packets directly to each other (after establishing a direct connection).

In most cases, a direct connection is preferable to a relayed connection because it has better throughout and reduced latency.

Tailscale's ability to establish a direct connection relies on its NAT traversal logic. This logic allows Tailscale to build a UDP tunnel and negotiate a pair of ports. In most cases, Tailscale succeeds in establishing direct connections. However, certain network configurations can pose challenges, leading Tailscale to use relayed connections as an alternative.

Relayed connections

A relayed connection is a connection between two devices that send packets to each other through a DERP relay server.

Tailscale operates a fleet of DERP relay servers worldwide. Any device that can open an HTTPS connection to an arbitrary host can build a tunnel using these DERP relays. These servers are reliable but have some quality of service (QoS) characteristics, so they are not as fast as a direct connection.

One of the most common causes of performance issues is using a relayed connection where a direct connection is possible.

Determine your connection type

To determine your Tailscale connection type, start by attempting to communicate between devices. Then, check the output of the tailscale status command. If the output includes the word “direct,” the connection is direct. If it includes the word “relay,” the connection is relayed.

If a device uses direct connections, the output includes the word “direct.” The following code block contains an example output from a device using direct connections.

100.113.160.82  testmy  tagged-devices linux    active; offers exit node; direct 140.82.13.138:41641

If a device uses relayed connections, the output includes the word “relay.” The following code block contains an example output from a device using relayed connections.

100.104.93.78   localhost-0          jay@         android active; relay "tor"

You can also use the tailscale ping command to check if a device uses direct connections. The following example output shows that the device can use a direct connection.

> ubuntu@living-razorfish:~$ tailscale ping testmy
pong from testmy (100.113.160.82) via DERP(nyc) in 130ms
pong from testmy (100.113.160.82) via DERP(nyc) in 37ms
pong from testmy (100.113.160.82) via DERP(nyc) in 50ms
pong from testmy (100.113.160.82) via DERP(nyc) in 38ms
pong from testmy (100.113.160.82) via 140.82.13.138:41641 in 35ms

The first few packets go to the nearest DERP server while Tailscale negotiates the direct connection. After establishing a direct connection, the packets go directly to the destination.

If Tailscale can’t establish a direct connection, the tailscale ping command gives up after 10 attempts.

> ubuntu@living-razorfish:~$ tailscale ping localhost-0
pong from localhost-0 (100.104.93.78) via DERP(tor) in 53ms
pong from localhost-0 (100.104.93.78) via DERP(tor) in 196ms
pong from localhost-0 (100.104.93.78) via DERP(tor) in 50ms
pong from localhost-0 (100.104.93.78) via DERP(tor) in 214ms
pong from localhost-0 (100.104.93.78) via DERP(tor) in 273ms
pong from localhost-0 (100.104.93.78) via DERP(tor) in 274ms
pong from localhost-0 (100.104.93.78) via DERP(tor) in 282ms
pong from localhost-0 (100.104.93.78) via DERP(tor) in 273ms
pong from localhost-0 (100.104.93.78) via DERP(tor) in 76ms
pong from localhost-0 (100.104.93.78) via DERP(tor) in 152ms
direct connection not established

Relaying packets through the DERP servers adds latency because the DERP servers have varied quality of service (QoS) characteristics that limit the maximum throughput. Consequently, it’s best to use direct connections whenever possible.

Some network configurations can prevent Tailscale from establishing direct connections. Two of the most common configurations that prevent direct connections include blocked UDP packets and hard NAT.

Obstacles to a direct connection

Tailscale can't always establish a direct connection between devices, and sometimes a direct connection might revert to a relayed connection. In most cases, the cause is that a device is using hard NAT or direct UDP packets are blocked.

Blocked UDP packets

Tailscale can only establish direct connections if the device supports sending and receiving UDP packets. If a device can only use TCP connections, all connections go through the DERP relay servers. For the DERP links, Tailscale encapsulates the WireGuard frames in a TLS stream over TCP.

Devices can't establish a direct connection if something on the network blocks direct UDP connections. However, you can still use a relayed connection. The only remediation is to ask your provider to unblock UDP packets.

Hard NAT

Hard NAT makes establishing direct connections difficult (if not impossible). Tailscale can’t establish a direct connection if both devices use hard NAT.

If a device uses hard NAT, you have a few options available to improve the odds of getting a direct connection. For example, using NAT-PMP or uPnP port mapping on your router often facilitates a direct connection.

Some firewall-specific mechanisms can improve the odds of direct connections. In general, look for something named “static port mapping” or similar configuration settings, which provide predictable (static) port numbers. Predictive port numbers allow Tailscale to reliably get direct connections through a firewall.

Many cloud platforms, like AWS, have a NAT gateway solution. Relayed connections on these services are often due to a hard NAT. You can expose public IP addresses for your Tailscale devices to ensure a direct connection. These IP addresses can be dynamic; you don’t need to use an elastic or static IP. If you ensure UDP port 41641 is not blocked and that outgoing UDP and TCP packets on port 443 are permitted, Tailscale can reliably serve direct connections.

By default, opening incoming UDP port 41641 on a device’s public IP address guarantees a direct connection from any peer where it is possible. You can configure this port by passing a value to tailscaled. On Linux machines, you can set it in /etc/defaults/tailscaled. This is useful if there is more than one endpoint behind a hard NAT public IP address, and you need to ensure direct connections to each. Set the port to a unique value and forward that port through to the correct endpoint.

For devices (such as exit nodes) that intentionally egress through a NAT gateway, you can use Tailscale’s Terraform templates to set up routing for incoming traffic through the public interface and egress through the NAT gateway.

Contact our Solutions Engineering team at se@tailscale.com for assistance deploying this. This allows the egress traffic to have a predictable public IP address, but the ingress traffic to establish a direct connection to the exit node.