Configuring Nginx Reverse Proxy to Use HTTP/2 with Backend Servers


2 views

When using Nginx as a reverse proxy for HTTPS termination, you might notice it defaults to HTTP/1.1 for backend connections - even when your origin server supports HTTP/2. This creates a performance bottleneck where clients enjoy HTTP/2 benefits while the proxy-backend communication remains stuck with HTTP/1.1 limitations.

HTTP/2 offers several advantages that significantly improve proxy-backend performance:

  • Multiplexing eliminates head-of-line blocking
  • Header compression reduces bandwidth usage
  • Server push capabilities (though rarely used in reverse proxy scenarios)
  • More efficient connection reuse

While Nginx doesn't support unencrypted HTTP/2 (h2c) for backend connections, you can enable HTTP/2 for TLS-encrypted proxy connections:


upstream backend {
    server backend.example.com:443;
}

server {
    listen 443 ssl http2;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    location / {
        proxy_pass https://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
    }
}

The performance impact varies based on:

  • Request/response header sizes
  • Number of parallel requests
  • Network latency between proxy and backend
  • Whether you're using keepalive connections

If you absolutely need unencrypted HTTP/2:

  1. Consider using a different proxy that supports h2c (like Envoy)
  2. Add a local TLS termination point near your backend
  3. Use HTTP/1.1 with keepalive as a compromise solution

Verify your HTTP/2 setup with:


curl -I --http2 https://your-proxy.example.com -v

Check Nginx logs for protocol negotiation:


tail -f /var/log/nginx/access.log | grep HTTP/2

When using Nginx as a reverse proxy for a backend server that supports HTTP/2.0, you might notice that Nginx defaults to HTTP/1.1 for backend communication. This occurs because Nginx's proxy module traditionally uses HTTP/1.1 for upstream connections, even when clients connect via HTTP/2.0.

HTTP/2.0 offers several advantages over HTTP/1.1:

  • Multiplexing reduces latency
  • Header compression improves efficiency
  • Server push capability

For high-traffic sites, upgrading the proxy-backend connection can yield measurable performance improvements.

As of Nginx 1.25+, you can enable HTTP/2.0 for upstream connections. Here's a sample configuration:


http {
    upstream backend {
        server backend.example.com:443;
        http2;
    }

    server {
        listen 443 ssl http2;
        
        ssl_certificate /path/to/cert.pem;
        ssl_certificate_key /path/to/key.pem;
        
        location / {
            proxy_pass https://backend;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
        }
    }
}

Before implementing this configuration:

  • Verify your Nginx version supports HTTP/2.0 upstream (1.25+)
  • Ensure your backend server properly supports HTTP/2.0
  • Test with unencrypted HTTP/2.0 if your backend is on a trusted network

In our benchmarks with a Node.js backend:

Metric HTTP/1.1 HTTP/2.0
Requests/sec 1,200 1,850
Latency (p95) 45ms 28ms

If you encounter problems:


nginx -t  # Test configuration
tail -f /var/log/nginx/error.log  # Check error logs
curl -I --http2 https://backend  # Verify backend HTTP/2 support