Boost Your Site’s Speed: Enabling and Tuning HTTP/2 in NGINX
Learn how to turn on HTTP/2 in NGINX, tweak its settings for real‑world traffic, and measure the impact with curl and wrk. A hands‑on guide for performance‑hungry developers.
14 Jun 2026, 18:20 UTC

Problem: High‑concurrency traffic hurts legacy HTTP/1.1 servers
When a site receives hundreds of simultaneous requests, the single‑threaded nature of HTTP/1.1 means each request can block others. The result is higher latency, wasted bandwidth, and a poor user experience. Many sites still ship with the default NGINX configuration that only speaks HTTP/1.1.
Thesis: HTTP/2 in NGINX can cut round‑trip time and increase throughput
HTTP/2 introduces multiplexing, header compression, and optional server push. These features let multiple logical streams share a single TCP connection, lowering the number of handshakes required and reducing the overhead of repetitive headers. In practice, enabling HTTP/2 on a production server often yields measurable speedups, especially for content‑heavy sites.
Section 1 – What is HTTP/2?
- Multiplexing: dozens of streams share one TCP connection, eliminating head‑of‑line blocking.
- Header compression (HPACK): reduces the size of repeated HTTP headers.
- Server push: server can pre‑send resources the client will likely request.
- TLS requirement: most browsers enforce TLS for HTTP/2; the protocol can run over plain TCP (h2c) but is rarely used in production.
Section 2 – Configuring NGINX for HTTP/2
NGINX supports HTTP/2 from version 1.9.5 onward, but the --with-http_v2_module flag must be present, and the underlying OpenSSL library must support TLS 1.2+ (OpenSSL 1.1.1 or 1.0.2+).
# Verify build flags and OpenSSL version
nginx -V 2>&1 | grep http_v2_module
nginx -V 2>&1 | grep OpenSSL
Once confirmed, add http2 to the listen directive inside your HTTPS server block:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# Recommended cipher list for TLS 1.2/1.3
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://upstream;
proxy_http_version 1.1; # keep‑alive and chunked support
proxy_set_header Connection "keep-alive";
}
}
Key points:
- Use
proxy_http_version 1.1if the upstream expects HTTP/1.1; otherwise HTTP/2 won’t be forwarded correctly. - Keep the
ssl_ciphersline up to date; older blocks can trigger handshake failures.
Section 3 – Performance Tuning
After enabling HTTP/2, you can fine‑tune two important knobs:
http2_max_concurrent_streams– limits how many streams a client can open simultaneously on one connection. The default is 128; raising it can help heavily parallel workloads but increases CPU load for header compression.- Gzip vs. Brotli – NGINX can still gzip responses, but Brotli is more efficient for HTTP/2. Use
gzip on;for compatibility, or enablebrotli on;if your OpenSSL supports it.
Example tuning block:
http {
http2_max_concurrent_streams 256;
gzip on;
gzip_types text/plain text/css application/javascript;
}
Worked Example: Verify HTTP/2 and Measure Gains
- Check that HTTP/2 is enabled
- Benchmark with
wrk - Compare results
- TLS requirement: If you can’t use TLS, HTTP/2 is rarely supported by browsers. h2c is an option for internal services but not for public sites.
- CPU overhead: Header compression and stream multiplexing consume extra CPU. On low‑resource hosts, too high
http2_max_concurrent_streamsmay lead to thrashing. - Client support: Very old browsers (<2015) don’t support HTTP/2. They will fallback to HTTP/1.1 automatically.
- Server push: Uncontrolled push can increase bandwidth usage. Disable it with
proxy_http2_push off;or selectively push only critical assets. - Confirm
--with-http_v2_moduleand OpenSSL ≥1.1.1. - Add
http2to thelistendirective and reload NGINX. - Run
curl -I --http2to verify the protocol. - Benchmark with
wrkor a similar tool to quantify gains. - Monitor
nginx_statusandtopto watch CPU usage; adjusthttp2_max_concurrent_streamsif necessary. - Optionally enable Brotli and fine‑tune gzip for best compression.
- Review push usage; disable if bandwidth spikes.
curl -I --http2 https://example.com/ | grep HTTP
# Expected: HTTP/2.0 200 OK
# HTTP/1.1 baseline
wrk -t12 -c400 -d30s https://example.com/ > http1.txt
# HTTP/2 test (same flags, but server listens with http2)
wrk -t12 -c400 -d30s https://example.com/ > http2.txt
| Metric | HTTP/1.1 | HTTP/2 |
|---|---|---|
| Requests/sec | ≈ 4500 | ≈ 6000 |
| Latency (ms) | ≈ 120 | ≈ 70 |
| CPU (%) | ≈ 35 | ≈ 45 |
Numbers will vary, but you should see a higher throughput and lower latency with HTTP/2, at the cost of a modest CPU increase.
Trade‑Offs and Limitations
Actionable Closing: Next Steps for Your Deployment
By following these steps, you’ll convert your NGINX server into a high‑throughput, low‑latency asset that better serves modern web traffic.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.