Home » Wiki » How to Enable HTTP/2 on Nginx Web Server?

How to Enable HTTP/2 on Nginx Web Server?

by | SSL Installation Guides

How to Enable HTTP/2 on Nginx Web Server

Enabling HTTP/2 in NGINX for Faster Page Load Speeds

HTTP2 is a major revision of the HTTP network protocol that was designed to improve page load performance by enabling multiplexing and concurrency. When implemented correctly, enable HTTP/2 on Nginx web server can lead to dramatic improvements in site speed by allowing the browser to request multiple assets in parallel over a single TCP connection.

The internet has come a long way since the early days of dial-up modems and slow connection speeds. Today’s web pages are packed with high-resolution images, videos, animations, and other bandwidth-hungry content that can significantly slow down page load times if not handled properly. To leverage the benefits of HTTP2, you need to properly configure your Nginx server.

When enabling HTTP2 on Nginx, follow the steps to upgrade Nginx to a compatible version, install SSL certificates, adjust settings to allow concurrency, and confirm HTTP2 is active. With correct configuration, implementing HTTP2 on your Nginx server will accelerate page loads and provide a faster experience for your users.

Prerequisites for Enabling HTTP/2 on Nginx

Before jumping into the configuration, we need to ensure the following prerequisites are met:

  • Nginx Version 1.9.5 or Higher: Earlier versions do not support HTTP2. Run nginx -v to check your installed version.
  • OpenSSL 1.0.2 or Higher: OpenSSL enables Forward Secrecy and other advanced TLS features required by HTTP2.
  • HTTPS/SSL Certificate: Since HTTP2 only works over HTTPS, you need a valid SSL certificate installed on your server.

That’s it! As long as your Nginx setup meets these requirements, you are ready to upgrade to HTTP2.

Step-by-Step Guide to Enable HTTP/2 on Nginx Web Server

Step 1: Modify Listen Directive in Nginx Config

All Nginx configuration is handled through the nginx.conf file. This can typically be found at /etc/nginx/nginx.conf or /usr/local/nginx/conf/nginx.conf depending on how you installed Nginx.

Look for the server block that corresponds to your site and modify the listen directive like so:

server {
listen 443 ssl http2;
... existing configuration ...
}

This tells Nginx to listen on port 443 for HTTPS traffic with HTTP2 enabled.

If you’re using multiple server blocks, be sure to update the listen directive in each one. The HTTP2 settings will apply to all HTTPS hosts and sites defined on your server.

Step 2: Ensure SSL Settings are HTTP2 Compatible

HTTP2 requires certain SSL certificate settings for optimal security and performance. Double check that your Nginx config sets:

  • TLS version 1.2 or 1.3: Older TLS versions have vulnerabilities.
ssl_protocols TLSv1.2 TLSv1.3;
  • TLS ECDHE/DHE cipher suites: Provides forward secrecy.
ssl_ecdh_curve secp384r1;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
  • OCSP stapling: For faster certificate revocation checks.
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8; # Google DNS server
  • Refer to Nginx’s SSL configuration recommendations for other optimizations like session caching and HSTS.

Step 3: Restart Nginx

After making the necessary updates to nginx.conf, verify the syntax is correct:

nginx -t

If no errors are reported, go ahead and restart Nginx to apply the new HTTP2 settings:

# For Linux:

sudo systemctl restart nginx

# For Windows:

nginx -s reload

That’s it! Nginx is now configured for HTTP2.

Step 4: Verify HTTP2 Is Working

To confirm everything is working as expected, we need to check if HTTP2 requests are being served by Nginx.

This can be tested using curl on the command line:

curl -I https://example.com -k

In the output headers, look for the presence of HTTP/2 200: this indicates HTTP2 is active:

HTTP/2 200
server: nginx

Alternatively, you can use online tools like https://tools.keycdn.com/http2-test to analyze the HTTP headers.

If you don’t see HTTP2 enabled, go back and review your Nginx configuration to spot any issues.

Performance Optimization with HTTP/2 Push

One of the powerful features unlocked by HTTP2 is server push. This allows the server to preemptively “push” website assets to the client cache without waiting for an explicit request.

Server push avoids round-trip latency and significantly speeds up page loads. Page resources like CSS, JS, images, fonts, etc. are ideal candidates for push.

Here is an example Nginx configuration that pushes style.css to clients:

http2_push /style.css;
location = /style.css {
root /var/www/site;
}

The http2_push directive cues Nginx to push that asset on all HTTP2 responses.

Push directives can also be added on individual location blocks to granularly control what gets pushed for specific URL paths.

While server push is an impactful optimization, use it judiciously based on real-world caching needs. Pushing already cached assets can waste bandwidth and memory.

HTTP/2 Server Push Plugins

Manually configuring resource hints can be time-consuming. Several Nginx plugins are available that automate HTTP/2 server push by analyzing asset links in HTML.

For example:

  • ngx_http2_push_preload: Parses HTML links and pushes those assets.
  • nginx-http-push-stream-module: Preloads resources from a defined configuration file.
  • nginx-push-stream-module: Provides a WebSocket endpoint for push stream subscriptions.

Evaluate your website’s link patterns to determine if these plugins can boost performance.

Tuning Nginx for HTTP/2

In addition to server push, we can also optimize Nginx’s core configurations to ensure maximum HTTP/2 throughput.

Increase Worker Connections

HTTP/2 allows thousands of requests to be multiplexed over one connection. The default `worker connections` value of 512 in Nginx is too low to take advantage of this.

Bump up the worker_connections to a higher value based on your traffic levels:

events {
worker_connections 8000;
}

This allows each Nginx worker process to handle thousands of multiplexed requests over a single HTTP/2 connection.

Monitor your connection usage and increase worker_connections further if needed.

Use epoll or kqueue

The default Nginx event loop mechanism on Linux is select(). This has scalability limitations under high loads.

Switch to either epoll or kqueue for faster event notification:

events {
use epoll;
# or
use kqueue;
}

epoll is Linux specific, while kqueue works on FreeBSD, macOS, and BSD variants. This optimizes how Nginx handles thousands of open connections.

Set Appropriate Connection Timeouts

With HTTP/1.1, it was common practice to keep shorter timeouts of 60-75 seconds to conserve resources.

However, HTTP/2 connections are persistent and reused for multiple requests. Hence, the default timeouts of 60s in Nginx are now too low.

Bump these timeouts to higher values like 300s:

http {
  keepalive_timeout 300s;
  client_header_timeout 300s;
  client_body_timeout 300s;
  send_timeout 300s;
}

Higher timeouts prevent HTTP/2 connections from being prematurely closed.

Increase Header Buffer Size

HTTP/2 uses compressed binary headers which can exceed the default 4KB header buffer configured in Nginx:

http {
large_client_header_buffers 8 16k;
}

Increasing this buffer to 8 16k prevents errors when receiving large HTTP2 request headers.

There are additional Nginx optimizations worth considering as well: enable gzip compression, increase cache sizes, implement request limiting, etc. based on your workload.

HTTP/2 Server Push Gotchas

While HTTP/2 server push can speed up page loads, incorrect use can also hurt performance. Here are some pitfalls to avoid:

  • Pushing on Every Page: Only push critical above-the-fold resources. Pushing everything bloats page size.
  • Pushing Too Many Assets: Excessive push wastes bandwidth and memory. Limit to 2-6 assets.
  • Pushing Already Cached Assets: Duplicate pushes create overhead without benefit.
  • Blocking Page Render: Push only completes after full asset download. Delay CSS/JS if needed.
  • No Push Prioritization: Browsers may bottleneck on non-critical pushed assets.

Measure real-world loading experience to fine-tune your push approach.

Fallback to HTTP/1.1

While most modern browsers support HTTP/2, some legacy clients may still connect via HTTP/1.1.

Nginx will seamlessly handle sending HTTP/1.1 responses to these user agents. But any HTTP/2 server push configurations will be ignored.

Use Nginx’s $http2 variable to conditionally push assets only for HTTP/2 capable clients:

if ($http2) {
http2_push /style.css;
}

Alternatively, use HTTP/1.1 Early Hints with Link rel=preload headers to achieve similar results.

Conclusion on Enable HTTP/2 on Nginx Web Server

Implementing HTTP/2 support on your Nginx server unlocks significant performance and security improvements for modern websites and applications. To enable HTTP2 on Nginx, you need to follow certain steps.

While the protocol itself introduces major optimizations like multiplexing and server push, additional Nginx tweaks like increasing timeouts, worker connections and response buffers are needed to maximize gains when enabling HTTP2 on Nginx.

Carefully planned server push of critical page assets can greatly improve perceptual speed for users. However, excessive push can be counterproductive so be selective when configuring HTTP2 on Nginx.

Follow the steps outlined in this guide on how to enable HTTP2 on Nginx and you will be able to get your Nginx stack upgraded to HTTP/2 easily. Measure site metrics before and after to validate the benefits of faster page loads.

Over time, as more legacy clients fade away, HTTP/2 will become the universal standard for web traffic. Adopting it now by enabling HTTP2 on Nginx will ensure your Nginx server is ready to deliver the fastest, most efficient user experiences going forward.