Today we release NGINX 1.17.0 – the latest version of the NGINX open source project, which is now the most popular web server on the Internet. This release also signals the start of the NGINX 1.17 development branch, following the release of NGINX 1.16.0 last month.
In this blog we discuss the NGINX versioning scheme, look back at what happened during the NGINX 1.15 development cycle, and look forward to what is in store with NGINX 1.17.
NGINX Versioning Explained
At NGINX, we maintain two branches in the NGINX source code repository, named mainline and stable:
- Mainline is the active development branch where the latest features and bug fixes get added. It is denoted by an odd number in the second part of the version number, for example 1.17.0.
- Stable receives fixes for high?severity bugs, but is not updated with new features. It is denoted by an even number in the second part of the version number, for example 1.16.0.
What It Means to Be “Stable”
At NGINX, the word “stable” refers to functionality and update frequency. It does not relate to software quality. The stable branch never receives new functionality during its lifecycle and typically receives just one or two updates, for critical bug fixes.
The stable branch has an annual lifecycle. Every April, we retire the current stable branch, after which, no further bug fixes are provided. This triggers two events:
- Firstly, the current mainline version is forked, to create the next stable version. The stable branch inherits all of the bug fixes, features, and other changes that went into mainline over the past year. Last month, NGINX 1.15.12 was forked to produce NGINX 1.16.0. Note that until the next mainline release, ”stable” is identical to the current mainline release, and may include new features that are just days old.
- Secondly, the mainline branch gets a “version bump”; that is, the second part of the version number is incremented to the next odd number. Ongoing development continues in the mainline branch, with new releases built from the mainline every 4–6 weeks. Today marks the first release on the NGINX 1.17 mainline with NGINX 1.17.0.
Which Branch Does NGINX Plus Use?
NGINX Plus, the commercial version of NGINX, is maintained in a separate, private code repository. It is always based on the latest version of NGINX mainline, merged together with the additional closed source features and capabilities that ship with NGINX Plus. At the time of writing, the latest version of NGINX Plus is R18, based on NGINX 1.15.10.
Which Branch Should I Use?
We generally recommend using the mainline branch. This is where we commit all new features, performance improvements, and enhancements. We actively test and QA the mainline branch, and as the source of NGINX Plus builds it is completely suitable for production use.
If you are concerned about the overhead of monitoring the mainline branch for new features and bug fixes, then using the stable branch means that you only need to review new functionality once a year, and bug fixes on an infrequent basis.
NGINX 1.15 in Review, AKA What’s New in Stable NGINX 1.16
The NGINX 1.15 development cycle carried some major development efforts, including improvements to UDP proxying in the Stream module, the Random load?balancing method, support for TLS 1.3 early data, dynamic loading of SSL certificates, and more. Before we look at the most significant enhancements in more detail, here’s NGINX 1.15, by the numbers:
- 13 mainline releases (one every 4 weeks on average)
- 16 bug fixes
- 19 new features
- 3000 net new lines of code (increasing the codebase by 2.2%)
Improvements to UDP Proxying
Support for proxying and load balancing UDP traffic was first introduced in NGINX 1.9.13. This enabled NGINX to sit in front of popular UDP applications such as DNS, syslog, NTP, and RADIUS to provide high availability and scalability of the application servers. The initial implementation was limited to UDP applications that expect a single UDP packet from the client for each interaction with the server.
Support for UDP sessions arrived in NGINX 1.15.0, which means that more complex UDP applications can be proxied and load balanced. These include OpenVPN, VoIP, and virtual desktop solutions. NGINX 1.15.7 added the proxy_requests directive which provides more control over how a virtual UDP session is “connected” to a backend server. Furthermore, handling of all UDP applications – simple or complex – is also significantly faster.
TLS 1.3 Early Data
One of the performance improvements introduced in TLS 1.3 is called 0?RTT (zero round?trip time). It makes it possible to resume TLS sessions faster, by reducing the number of round trips between client and server when re?establishing an encrypted session. NGINX now supports 0?RTT through the ssl_early_data directive.
Dynamic Certificate Loading
When managing TLS/SSL certificates for secure sites and applications, NGINX is typically configured to specify the certificate and associated private key as files on disk. The certificate and key for each hostname are specified as static configuration in a separate server block, and loaded at NGINX startup. NGINX 1.15.9 enabled dynamic loading by using the SNI variable $ssl_server_name to locate the file on disk. NGINX 1.15.10 extended this further by allowing the certificate data to be obtained from a variable.
Random Load Balancing and the “Power of Two Choices”
NGINX 1.15.1 added the random load?balancing method, specifically aimed at distributed load?balancing deployments where multiple NGINX instances are load balancing to the same set of backend servers.
A simple variation on random load balancing, yet one which is proven to improve load distribution, is to select two backend servers at random and then choose the one with the lower load. We call this Random with Two Choices. The goal of comparing two random choices is to avoid making a bad load?balancing decision (even though the choice might not be the best among all the available servers). By avoiding the backend server with the greater load, each load balancer can operate independently, without sending spikes of traffic to individual backend servers. Thus we get the benefits and computational efficiency of random load balancing but with demonstrably better load distribution. Random with Two Choices is now the default load?balancing method configured by the official NGINX Ingress Controller for Kubernetes.
Two-Stage Rate Limiting
NGINX can enforce request rate limits by rejecting excessive requests or by delaying excessive requests until they can be processed within a defined rate limit. NGINX 1.15.7 enabled both of these enforcement methods to be combined in two?stage rate limiting, whereby excessive requests are initially delayed, and ultimately rejected if they cannot be processed according to the limit. Enable two?stage rate limiting with the delay parameter to the
Thanks to Vladislav Shabanov and Peter Shchuchkin for this contribution.
Listen Port Ranges
NGINX 1.15.10 can listen on a range of ports with both the HTTP and Stream modules, implementing a commonly requested feature for FTP proxying.
- Richer support for functions and prototypes, including “fat arrow” functions
- Broader support for non?integer numbers
- Binary literals, and conversion to and from bytes
What’s Coming in NGINX 1.17
The first release on the NGINX 1.17 mainline is already here. NGINX 1.17.0 includes support for variables in bandwidth?limiting configurations with the limit_rate directive and also allows the include directive to be used in all configuration contexts, even inside an if block.
Development has also started on support for QUIC and HTTP/3 – the next significant update to the transport protocols that will deliver websites, applications, and APIs. This is a significant undertaking, but likely to arrive during the NGINX 1.17 development cycle. To get the latest insights on the NGINX roadmap and, our other open source projects and products, join us at NGINX Conf, our annual user conference, this September 9–12 in Seattle.