Sometimes, the right combination of features and timing has to coincide for something interesting to happen. My colleague, Paul Lu, and I at the University of Alberta, feel it’s time to consider the re-inclusion of Forward Error Correction (FEC) in QUIC. Specifically, a modified and selective form of FEC for only high-priority resources (for example, JS, HTML and CSS) as FEC for all data is too expensive, but FEC for selected resources might help lower page-load times.
What is FEC?
FEC is a strategy to systematically add redundant, error-correcting metadata to be able to recover the lost data at the receiver. Consequently, when blocks or packets are lost on the network, the data can be recovered instead of retransmitted. Therefore, FEC avoids incurring high Round-Trip Time (RTT) latencies by trading off data transmission overheads for time and, if necessary, computational overheads to compute the lost data.
The specific FEC algorithm or strategy can be debated and selected from many good choices at hand. However, the argument is that a beneficial trade-off can be found between the overheads of FEC versus the poor user experience due to lost packets and delays.
Why is it relevant now?
Early versions of QUIC had FEC, but for all resources. The redundancy overheads for all data were considered too high, and the feature was dropped.
For HTTP/3, there is a simple mechanism for resource prioritization (RFC 9218), to replace a more complicated prioritization mechanism from HTTP/2. Combining the RFC 9218 priority mechanism with selective FEC might now make sense to reduce page load times.
The resources that need to be downloaded completely before getting used, such as JS, HTML, and CSS, are given high priority values, and FEC is only used on those resources. The resources that can be used incrementally (for example images) can take advantage of QUIC’s multi-streaming to avoid the head-of-line blocking problem in the case of packet loss.
FEC reduces the need for retransmission times by >100 ms
In our proof of concept, a simple policy of only using FEC for priority level 0 had the desired effect.
We implemented this idea over ngtcp2 and got some promising early results. For the FEC part, we used the OpenFEC library, which includes the implementation of Reed-Solomon (RFC 5510) and LDPC codes (RFC 5170).
Figure 1 shows the arrival order of QUIC frames for a simple workload of a high priority resource (green, 7.2 KB) and a low priority resource (pink, 26.5 KB) when the RTT was 100 ms.
Without FEC, the HTTP client needs to wait for 103 ms to get the retransmission of a lost QUIC frame and complete receiving the high-priority resource. However, using Reed-Solomon we need to send a 1.8 KB repair file to be able to recover two lost QUIC frames and finish downloading the high priority resource at 7 ms while receiving their retransmissions took 109 ms.
Earlier attempts at FEC in QUIC were deemed too expensive. An early form of prioritization in HTTP/2 might have been too complicated. But, a combination of selective FEC, the simple prioritization of RFC 9218, and a policy of only using FEC for high-priority resources might be the combination to make the mechanisms worthwhile.
For more information, see our ANRW 2022 presentation.
Nooshin Eghbal is a PhD candidate in the Department of Computing Science at the University of Alberta supervised by Dr Paul Lu.
The views expressed by the authors of this blog are their own and do not necessarily reflect the views of APNIC. Please note a Code of Conduct applies to this blog.