Introducing a Technology Preview of NGINX Support for QUIC and HTTP/3

by

in

We are pleased to announce the technology preview of QUIC+HTTP/3 for NGINX at a special open source repository. This is pre‑release software, based on the IETF QUIC draft and is maintained in a development branch, isolated from the stable and mainline branches. The release is the culmination of several months of initial development, and is now ready for interoperability testing, feedback, and code contributions.

A demo site enabled with the NGINX QUIC+HTTP/3 implementation is available at https://quic.nginx.org/.

[Update:

Understanding HTTP/3

In this fast‑paced world, the Hypertext Transfer Protocol (HTTP) has been a remarkably stable constant for over two decades. The HTTP/1.1 standard was published in 1999 and has become the ubiquitous transport protocol for web applications and APIs. The protocol remained the same over the next 21 years despite the huge changes to the apps and services it is used to transport.

At this point the astute reader may be asking, “but what about HTTP/2?”. This is a very good question. The HTTP/2 standard was published in 2015, and has seen steady adoption to the point where 45% of Internet‑facing websites support HTTP/2. However, this statistic belies the reality that the use of HTTP is quite different on the public Internet compared to the “last mile” (the runtime infrastructure).

The reality of modern Internet infrastructure is that HTTP/2 is very rarely deployed end to end. It is designed to solve problems that manifest most clearly on the public Internet, where latency is unpredictably high and problems with one HTTP request can delay subsequent requests. Inside the application runtime environment – for example, a public cloud or private data center – latency is low, network reliability is excellent, and the ability to directly inspect HTTP/1.1’s text‑based transport stream is of more value than the efficiency of HTTP/2’s binary transport stream.

HTTP/2 has by and large improved the user experience on browsers and mobile devices, because it’s well suited to the environment between the client and the “edge” of the runtime infrastructure. At that point it is typically proxied into a runtime environment where HTTP/1.1 is used. The edge is most likely to be a CDN provider, or a reverse‑proxy load balancer that handles traffic entering the runtime environment.

Typical hybrid deployment of HTTP versions

This hybrid approach of using HTTP/2 and HTTP/1.1 to deliver websites and applications works well. So why propose yet another new protocol, HTTP/3?

The primary innovation of HTTP/2 is to multiplex several HTTP requests over a single connection that uses TCP as the low‑level transport. Unfortunately, TCP has inherent limitations that constrain the performance and user experience of websites and applications. The TCP standard was originally published in 1981 and has been astonishingly successful as a general‑purpose transport protocol. However, when you multiplex several independent requests over the same connection, they all become subject to the reliability of that connection. If a packet for just one request is lost, all of the multiplexed requests are delayed until the lost packet is first detected and then retransmitted.

HTTP/3 is based on the QUIC transport protocol, which is designed specifically to support multiplexed connections without depending on a single TCP connection. QUIC instead uses UDP as the low‑level transport mechanism for moving packets between client and server, and implements a reliable connection upon which HTTP requests are made. Notably, QUIC also incorporates TLS as an integral component, not as an additional layer as with HTTP/1.1 and HTTP/2.

High-level overview of HTTP transport stacks

The goal of QUIC is to provide a high‑performance, high‑reliability, high‑security transport protocol for HTTP/3 (although QUIC is also suitable for non‑HTTP traffic). Semantically speaking, HTTP/3 itself is very similar to HTTP/2. However there is no explicit versioning of HTTP – https://www.example.com might support one or more of HTTP/1.1, HTTP/2, and HTTP/3. How do clients (web browsers) know which version of HTTP to use?

The versioning issue first arose with the introduction of HTTP/2, which solved it by using the TLS handshake to detect whether the client and server are capable of communicating over HTTP/2. That way, the client knows how to talk to the server before the connection is even established. However, QUIC’s use of UDP instead of TCP as the underlying transport protocol presents a new challenge – how does the client know which type of connection to request initially, TCP or UDP? The solution is for the client to establish a TCP connection for the initial HTTP request. The response from a server that supports HTTP/3 includes the Alt-Svc header to specify the UDP port on which it is listening for HTTP/3 traffic. In addition, the browser remembers which sites support QUIC to eliminate the overhead of the Alt-Svc–based discovery method.

NGINX QUIC+HTTP/3 Preview

Today we announce the initial release of the official QUIC and HTTP/3 implementation for NGINX, the http_v3_module. This is a technology preview and must be considered experimental – it is not for production use. At the time of writing, the QUIC standard is not yet finalized, and this initial release is implemented against a subset of the current draft.

Following several months of design and development, the http_v3_module is ready for interoperability testing. We also welcome general feedback and code contributions. Note that the http_v3_module is not available in the NGINX Open Source mainline development branch (nor any release of NGINX Plus); because it is still experimental, it is in a dedicated development branch at https://hg.nginx.org/nginx-quic.

Note also that this QUIC+HTTP/3 implementation is all‑new, and not related to the patch provided by Cloudflare as part of its quiche project.

For those familiar with NGINX configurations, enabling QUIC+HTTP/3 is quite straightforward.

server {
listen 443 ssl; # TCP listener for HTTP/1.1
listen 443 quic reuseport; # UDP listener for QUIC+HTTP/3

ssl_protocols TLSv1.3; # QUIC requires TLS 1.3
ssl_certificate ssl/www.example.com.crt;
ssl_certificate_key ssl/www.example.com.key;

add_header Alt-Svc ‘h3=”:443″‘; # Advertise that HTTP/3 is available
add_header QUIC-Status $quic; # Sent when QUIC was used
}

For more information about building NGINX from the nginx-quic repo, and recommended configuration, see the README. In addition, a demo site with the http_v3_module enabled is available at https://quic.nginx.org/. From here you can check whether your browser already supports QUIC, and compare HTTP/3 interoperability with your own build of nginx-quic. Given the draft status of QUIC, you may need to use development versions or the very latest builds of the common browsers to enable a QUIC connection.

Thanks for trying nginx-quic, and we look forward to your feedback:

  • If you have a comment or suggestion, you can add it to the comments section below or send it to an NGINX mailing list.
  • If you encounter a bug or unexpected behavior, or need help with troubleshooting, please send your message to an NGINX mailing list; the lists are actively monitored by NGINX Engineering.