Streaming video, multiplayer games, and other real-time experiences depend on responsive, low latency networking. Learn how Low Latency, Low Loss, Scalable throughput (L4S) can reduce network delays and improve the overall experience in your app. We'll show you how to set up and test your app, network, and server with L4S.
♪ ♪ Shawn: Hi, I am Shawn. I am an engineer on the Internet Technologies team. Today, we are going to talk about reducing network delays in your app with L4S. L4S stands for Low Latency, Low Loss, and Scalable throughput. It is an incredible technology that dramatically improves the performance of apps where network latency can impact the user experience. To name just a few benefits, it can help your app reduce content load time, improve video quality, and bring more responsive collaboration between users.
Today, we'll first explore how L4S works and how it reduces network delays. Then, we will go over how to prepare your app for L4S and how to turn on L4S on your server. Finally, we will talk about the steps you can take to configure an L4S network and test your app. First, let's explore the benefits of L4S and how it works.
A busy network can be especially challenging for apps that depend on features like real-time audio and video. When the network is used by many devices at once, it can often cause high latency and packet loss in these types of apps. For example, you might have experienced delays or video stalls during a video call when someone else using the same network is watching a movie or downloading a video game. To show you how much L4S can help in such a difficult situation, we have made a sample app that makes video calls between two devices. I will show you two video calls with my sample app made at different times, one without L4S and the other with L4S turned on. For both these calls, I used the same constrained network with low bandwidth. In addition, there are also multiple other devices actively using the same network at the same time. Let's see this in action. You will notice a remarkable difference in video quality between the two calls. The legacy one shows occasional video stalls and delays, especially during motion. However, with L4S, the video is smooth and responsive, without any significant delays. Now let's analyze the video calls we have just witnessed to understand what was happening. In this demo, L4S allowed our app to achieve significant improvements across all key networking metrics. First, let's look at the distribution of round trip time of packets during these video calls. A shorter round trip time indicates a lower and better latency on the network. For an interactive app like this, the tail latency is extremely important, as it shows the worst case that a user experiences. Our test network has a minimum round trip time of 20 milliseconds. However, without L4S, packets experienced a round trip time of up to 45 milliseconds. But with L4S turned on, even the worst-case latency was cut by 50% and reduced to less than 25 milliseconds.
Next, let's look at packet loss. A lower packet loss represents a more reliable connection between devices. With the legacy one, packet loss rate reached over 40%. But with L4S, packet loss in our video call was nearly eliminated. That means much fewer frame drops or stalls due to loss of data. The improved latency and packet loss rate translated directly into better rendering metrics of our video call. First, let's look at the video stall percentage. A lower stall percentage means fewer freezes during a video call. Without L4S, we experienced video stalls in our app from time to time. But with L4S, video stalls were almost completely eliminated.
Next, let's look at received video frame rate. A higher and more consistent received video frame rate means a richer and smoother video call. With L4S, received video frame rate was above 25 frames per second for most of the time. However, the legacy one sometimes dropped to as low as 0 frame per second, which means a complete video stall. Altogether, these improvements give a much better user experience even in a constrained network. You can bring these same improvements to your app by adopting L4S. Now, let's take a look at how L4S works.
We see such remarkable improvements, because L4S reduces queueing and packet loss. Let's first take a look at how a queue builds up in a network. When a packet is sent from your app, it is routed through different network hops before reaching your server. This set of hops your packet traverses is called a network path.
On a path through a network, you can only deliver data end-to-end at the rate that is supported by the slowest hop, which is called the bottleneck. For many people, this is their internet service provider connection, and the highest rate it can handle packets determines the maximum throughput supported on the path. If the sender exceeds the maximum throughput, a queue will form at the bottleneck, causing delays for subsequent packets. Without L4S, the queue will continue to grow until the queue cannot accommodate any more packets. When that happens, packets are dropped, harming both latency and throughput. L4S solves this problem through a collaboration between the client, the server, and the bottleneck. With L4S, a client or server sending packets needs to signal that they will cooperate to manage network congestion.
To do this, an L4S-capable sender will use a technology called Explicit Congestion Notification, also known as ECN. When transmitting a packet, the sender indicates support for L4S by using the ECN bits in the packet's IP header. When an L4S hop receives these packets, it will apply L4S queue management to them.
When a queue starts to build up at the bottleneck, L4S queue management will indicate that there is congestion by setting a different ECN label on the packets. This label indicates that the network has experienced congestion before forwarding them to the next hop. Upon receiving these packets, the receiver counts the number of packets marked with the congestion label and reports the number back to the sender. When the sender receives this number, it uses this feedback to understand the congestion on the network. The sender then adjusts its sending rate according to the level of congestion at the bottleneck, so that it does not exceed the maximum throughput. With an adjusted sending rate, the sender can avoid building a large queue of packets at the bottleneck. This allows L4S to maximize its throughput and achieve low end-to-end latency at the same time. Now, let's explore what you need to do to enable this collaboration to deliver these benefits to your users. First, let's discuss how you can prepare your app for L4S. Using networking APIs in URLSession and Network framework is the best way to adopt L4S in your app. If your app uses HTTP/3 or QUIC within these frameworks, L4S support is automatically built in. You don't have to make any code changes to your app. Alternatively, if your app uses HTTP/2 or TCP, iOS 17 and macOS Sonoma have built-in L4S support for downloads on these protocols. These are the best ways to add L4S support to your app because they do not require any code changes. However, if your app uses a custom protocol, there are a few things you'll need to implement in order to support L4S in your app. RFC 9330 is a good starting point to learn about L4S requirements. You will need to implement a few new behaviors. For example, your protocol needs to understand L4S congestion feedback from the network and adjust its sending rate accordingly. To do that, you need to implement a scalable congestion control algorithm. Then, you need to make sure your app sends L4S traffic only when the network lets ECN bits pass through. To do that, implement an ECN validation mechanism that checks for any network issues that may be interfering with ECN, such as ECN bleaching. When acting as a receiver, your protocol also needs to have a relay mechanism to echo back the network's ECN feedback to the sender. If your implementation is based on Network framework, you can use the ECN property on your packet metadata to send and receive ECN flags for your custom protocol. If you are using sockets, you can use the set socket option or send and receive message system calls to send and receive ECN flags.
Now we have covered how to prepare your app for L4S, let's explore how to set up your server. If your app uses QUIC, your server's implementation of QUIC also needs to support L4S and ECN markings. There are numerous QUIC implementations available on the server side. Ask your server provider about how to enable ECN and L4S. If they do not support sending L4S traffic yet, you can still enable ECN to receive L4S traffic on your server. Now is a great time to encourage them to fully support L4S.
If your app is using TCP, you will need to add L4S support to your server's TCP implementation. For Linux based server, follow instructions on this GitHub page to add support to your server. You can also find more details from the article in the related items for this video. For all other server platforms, please consult your server provider, as there may be additional configurations or changes required in order to support L4S. Now that we have covered how your app and server can be set up for L4S, let's explore how to set up an L4S network to test your app. First, let's review what makes a network L4S-capable. The network must not block ECN markings. ECN markings are used to communicate information about the network between the sender, the bottleneck, and the receiver. If your network interferes with ECN markings, L4S will not work. The documentation has steps you can follow, along with additional tools, that you can use to verify if your network is ECN compatible. Next, the network bottleneck must support L4S queue management. This is essential to being able to see the benefits of L4S. Once you have verified that your network is ECN compatible, you just need to add L4S queue management to the bottleneck. To set up a test network that supports L4S queue management, the best way is to use Internet Sharing.
In macOS Sonoma, Internet Sharing supports L4S queue management. When a device joins the network created by a Mac with Internet Sharing, the Mac itself becomes an additional network hop between the device and the server. If you configure the Mac to be the bottleneck on the network, it will apply L4S queue management to traffic going through it, allowing you to build a complete L4S network. To enable Internet Sharing in macOS, navigate to the Internet Sharing pane in System Settings. Click the disclosure button to choose the interface to share and the interface to which your test device will connect.
To make the Mac act as a bottleneck on this network, you need to throttle its bandwidth. Use this ifconfig command in Terminal with the interface you are sharing, as well as the interface your device will connect to. Replace the interface name in this command with the name of the interfaces you are using, for example, en1. Then, join the network on your test device and test your app to see the benefits of L4S. To reverse the bandwidth throttling on the Mac, you can either reboot or run the same ifconfig command but change the bandwidth to 0 instead of 10 megabits per second.
In iOS 17 and macOS Sonoma, L4S will be progressively rolled out to a random set of users. To ensure your test device has L4S turned on, navigate to Developer Settings and turn on L4S. In macOS, you can enable L4S by running this defaults write command before testing. If your network or server does not support L4S, TCP and QUIC will continue to work in the legacy mode. However, you should turn L4S on and test your application to identify any issues. Provide feedback using the Feedback Assistant if any issues arise. The documentation also provides helpful information about debugging and testing L4S in your app. I am so excited that apps and networks are now able to support reduced latency and reduced packet loss with L4S.
Test your app in iOS 17 and macOS Sonoma today on networks that support L4S as well as on networks that do not. Work with your server or CDN provider to enable support for L4S on your app's servers, if they haven't already done so. Use the Feedback Assistant to report any issues you encounter with L4S turned on in your app. Thanks for watching. I am looking forward to building even better apps with you using L4S. ♪ ♪