I’ve written several blogs about how IPv6 is faster, and how that results in higher Google search rankings, and that’s good for sales. My presentation at NANOG76 went into it at some depth. The question everyone asks:
Why is IPv6 faster?
I don’t know. So let’s look at some measurements.
This is from APNIC data, using the ten largest mobile carriers in the world, where I know what transition mechanism they’re using. There are four carriers shown who provide native IPv4-IPv6 dual-stack to the handset: they’re all right at 1% failure rate. I should note that the two at 50ms and -50ms are in Bhutan and Trinidad and Tobago, so there may be other factors at play in the speed of their connectivity. The other two dual-stack wireless carriers are in the US and Taiwan, and IPv6 and IPv4 are nearly exactly the same speed.
Among the mobile carriers running NAT64, only the Australian has a faster IPv4, by just one millisecond. For all the rest, IPv6 is faster. Why?
With native dual-stack, the carrier provides both an IPv4 address and an IPv6 address to the handset. With NAT64, the carrier provides only an IPv6 address. If the client needs to reach an IPv4-only server, it has to go through translation (Network Address Translation, NAT64). Apple requires that all iPhone apps just work with NAT64. For Android, if there’s something in the app that uses IPv4 explicitly (or just an IPv4-only library), there’s a little NAT46 function in Android that translates to IPv6, since that’s the only address the handset has. That function is called CLAT (client translation), and when combined with NAT64, is called 464xlat.
It’s possible that going through a NAT64 introduces some latency, though I’ve never seen a NAT64 add measurable latency. Maybe the NAT64 is on a suboptimal path. It’s also possible that the latency difference is not in the NAT64 end, but on the CLAT end: maybe the handset translates from IPv4 to IPv6 before sending traffic out, and the handset software is causing the speed difference.
What about all the fixed line providers with speed differences?
These are just the largest networks in North America. This does suggest a loose correlation between failure rate and latency. Generally (but not closely) networks with more IPv6 failures show better IPv6 performance.
Most operating systems and browsers, including mobile handsets, use an algorithm called Happy Eyeballs to make sure the deployment of IPv6 doesn’t harm performance. That algorithm basically says:
- Send DNS queries AAAA then A, as separate queries but in quick succession.
- Send to an IPv6 name server If you have both an IPv6 name server and IPv4 name server configured.
- Don’t wait for both responses.
- If A comes first, wait 50ms (e.g.) for AAAA, in case it was just that the resolving name server didn’t have it cached.
- Begin your connection.
- If connection fails (e.g., no response in 250ms), and you got multiple DNS responses, try another: maybe use the other address family.
There’s an odd race condition here, I think. Let’s say you fire off your AAAA DNS query (IPv6) and your A DNS query (IPv4) within a millisecond. For whatever reason, the resolver you’re querying only has the A record cached, so it looks up the auth server for the AAAA query, but immediately responds with the A response. Your system waits 50ms for the AAAA response, and if it doesn’t arrive, it begins the connection, sending a TCP SYN over IPv4. Then the AAAA response arrives, so it begins the connection, sending a TCP SYN message over IPv6. Based on that timing, the TCP SYN-ACK is received over IPv4 before it’s received over IPv6.
That’s just an example. Any time the TCP SYN-ACK is received over IPv4 after the TCP SYN is sent over IPv6, but before the TCP SYN-ACK is received over IPv6, the system will use IPv4, and APNIC will count it as an error.
There could be reasons other than DNS why the SYN-ACK is received over IPv4 first. Maybe the TCP ACK required retransmission. Maybe the IPv6 attempt took 260ms (or whatever the connection timer was) and the IPv4 attempt completed in 9ms. Maybe there are different timers than the ones suggested by RFC8305 and some operating system gives a smaller head start to IPv6 but on some networks IPv4 is faster than IPv6 round trip time. Maybe we’re measuring old implementations of Happy Eyeballs (rfc6555).
tl;dr I think Android CLAT hurts IPv4 and I think there’s a race condition in Happy Eyeballs that can make IPv6 look faster in statistics by dropping some cases where it’s slower. If you want to enable IPv6 on your web site, here’s how:
The IPv6 On Button
Step 1. Find your web host below and follow the instructions.
Step 2. Update DNS–create a AAAA record with a test name (www6) pointing to your IPv6 address.
Step 3. Test the site from your machine, your phone, and https://ipv6-test.com/validate.php
Step 4. Update the test name to your web site name.
You should follow up to make sure your web logs tools don’t get confused, and if you’re monitoring the site, make sure to monitor separately for the IPv4 and IPv6 addresses, or users will have a bad experience if one is unavailable.
That’s it! Usually done in ten minutes.
Nothing to do, it’s on by default.
If you’re with another cloud company and they don’t have good IPv6 support, CloudFlare will front-end IPv6 for you.
Log into your portal and for “IPv6 Configuration” choose “Enable.”
Amazon Web Services (AWS)
Assuming you’re running your own server on EC2 in a VPC, you’ll need to start by adding IPv6 to the VPC. From the VPC Console, Actions > Edit CIDRs > Add IPv6 CIDR.
Then go to the EC2 console and find which Subnet your EC2 instance is on and add IPv6 to it. In the EC2 Console view, the Subnet ID will be on the bottom right. Subnet ID > Actions > Edit > Add IPv6 CIDR > any two-digit hex string, like 00.
Then update the Route Tables to route all IPv6 traffic from the subnet to the Internet Gateway. From the Route Tables console, Actions > Edit Routes > add 0::/0 with Target your IGW.
Then update your Security Groups to allow traffic from ::0/0. Security Groups Console > Actions > Edit Inbound Rules > Add Rule > then mirror your IPv4 policy. If you allow from “Anywhere,” then make sure that’s selected and includes ::/0.
Then edit your instance to assign an IPv6 address from it. Console > Actions > Networking > Manage IP Addresses > Add IPv6 Address.
If you’ve configured the server yourself (Apache or nginx) you may need to update your “listen” statements.
Enable IPv6 simply by prefixing your CNAME in DNS with “dualstack.” For example:
If you have a custom host name, follow the link to email Fastly Support saying, “I want to add IPv6 to my server www.example.com.”
Server instances can be configured for IPv6 according to their operating system, but IPv6 support for web servers hosted on Softlayer CDN only get IPv6 via Akamai.
IBM Cloud CDN
Change to a different CDN or use CloudFlare (above).
You’ll need a Basic Load Balancer or VNet to get IPv6. (Microsoft’s documentation does not state whether Standard Load Balancer supports IPv6).
The Load Balancer option comes with a lot of troubling limitations:
You can’t add IPv6 to your existing VM. You’ll have to create a new one behind your Load Balancer. Your Network Security Group policies won’t apply to IPv6. You can’t do it in the GUI–you have to use the CLI or PowerShell. I’d suggest changing to a different cloud or CDN or adding CloudFlare (above). https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-ipv6-overview
The Virtual Network instructions say you can upgrade in place, but they are less clear about security, but the CLI or PowerShell is still the only way to do it. https://docs.microsoft.com/en-us/azure/virtual-network/ipv6-overview
Rackspace gives pretty good examples on using Neutron to configure a port and using cURL to configure a port.
You’ll need to configure Load Balancing. There are several ways to configure Load Balancing to support IPv6, given at the links from https://cloud.google.com/load-balancing/docs/ipv6
Note that Google charges for using a static IPv6 address: “Reserved IPv6 addresses are charged at existing rates regardless of whether they are in use or not.” (“Existing rates” currently $0.01/hour for unused addresses, but since Google charges “regardless of whether they are in use or not” they’ll charge, so something like $7.20/month).
The better option is to find another cloud or CDN, or add CloudFlare (above).
If you have a dedicated server or virtual private server, you’ll pay $5.95/month to reserve an IPv6 address. Find a different host or use CloudFlare (above).
This list isn’t anywhere near exhaustive. If your provider isn’t listed, search for them by name plus “IPv6.”
I can update this post as I learn of corrections or additions. I’ve also created a common Google Sheet where people can add comments and I’ll update the sheet.
EDIT:  @jeremyvisser on Twitter says the Australian provider switched to native dual stack. So IPv4 is slower for all NAT64 carriers shown.
*This article was originally published on Retevia