Implementing HTTP/2
1. Enabling HTTP/2
| Directive | Description | Example |
|---|---|---|
| listen | Enables HTTP/2 on a port using the http2 parameter |
listen 443 ssl http2; |
| ssl_protocols | Enables TLS 1.3 and 1.2 for HTTP/2 compatibility | ssl_protocols TLSv1.2 TLSv1.3; |
| ssl_ciphers | Recommended cipher suite for HTTP/2 and security | ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512; |
Example: Basic HTTP/2 Configuration
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
}
2. Configuring HTTP/2 Push
| Directive | Description | Default | Notes |
|---|---|---|---|
| http2_push | Enables or disables HTTP/2 server push | off |
Can be set per location or server block |
| http2_push_preload | Enables automatic preload of resources | off |
Requires http2_push to be enabled |
Example: Enabling HTTP/2 Push
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_private_key /path/to/key.pem;
location / {
http2_push /css/style.css;
http2_push /js/app.js;
}
}
Note: Server push is most effective when used with static assets like CSS, JS, or images that are known to be needed by the client.
3. Setting HTTP/2 Max Streams
| Directive | Values | Description |
|---|---|---|
| http2_max_requests | 1000 |
Maximum number of requests per HTTP/2 stream |
| http2_max_concurrent_streams | 100 |
Maximum number of concurrent HTTP/2 streams per connection |
Example: Configuring HTTP/2 Max Streams
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
http2_max_concurrent_streams 100;
http2_max_requests 1000;
}
4. Configuring HTTP/2 Body Preread
| Directive | Values | Description |
|---|---|---|
| http2_body_preread_size | 1m |
Sets the size of the buffer used for reading the HTTP/2 request body before processing. |
| http2_body_preread_timeout | 60s |
Sets the timeout for reading the HTTP/2 request body before processing. |
Example: Setting HTTP/2 Body Preread Size
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
http2_body_preread_size 2m;
}
Note: The
http2_body_preread_size directive is used to configure the size of the buffer for reading HTTP/2 request bodies. Increasing this value can help with handling larger payloads, but it also increases memory usage.
5. Setting HTTP/2 Timeouts
| Directive | Values | Description |
|---|---|---|
| keepalive_timeout | 65s |
Timeout for keep-alive connections. For HTTP/2, this should be set to a reasonable value (e.g., 65s) to allow for long-lived connections. |
| client_body_timeout | 60s |
Timeout for reading client request body. For HTTP/2, this is important to prevent hanging connections. |
| client_header_timeout | 60s |
Timeout for reading client request headers. HTTP/2 uses this to manage header processing time. |
| send_timeout | 60s |
Timeout for sending a response to the client. For HTTP/2, this ensures timely responses. |
Example: Configuring HTTP/2 Timeouts
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
keepalive_timeout 65s;
client_body_timeout 60s;
client_header_timeout 60s;
send_timeout 60s;
}
6. Optimizing HTTP/2 Performance
| Directive | Description | Default | Notes |
|---|---|---|---|
| http2_max_concurrent_streams | Maximum number of concurrent streams per connection | 100 |
Higher values may increase memory usage |
| http2_idle_timeout | Idle timeout for HTTP/2 connections | 30s |
Adjust based on expected connection lifetime |
| http2_max_field_size | Maximum size of a header field | 4k |
Can be increased for large headers |
| http2_max_header_size | Maximum size of the entire header block | 16k |
Increases memory usage if set too high |
Example: Configuring HTTP/2 Performance Settings
http {
# Enable HTTP/2
listen 443 ssl http2;
# Optimize concurrent streams
http2_max_concurrent_streams 200;
# Set idle timeout to 60 seconds
http2_idle_timeout 60s;
# Increase header field size limit to 8KB
http2_max_field_size 8k;
# Increase total header size limit to 32KB
http2_max_header_size 32k;
}
Performance Tuning Tips
- Monitor memory usage when increasing
http2_max_concurrent_streams - Adjust
http2_idle_timeoutto match application connection patterns - Use
http2_max_field_sizeandhttp2_max_header_sizeto handle large headers from services like OAuth or JWTs - Enable HTTP/2 Server Push for critical resources when appropriate
Note: HTTP/2 performance tuning is highly dependent on server hardware and traffic patterns. Start with conservative values and adjust based on monitoring data.
7. Understanding HTTP/2 vs HTTP/1.1
| Feature | HTTP/1.1 | HTTP/2 |
|---|---|---|
| Connection | Text-based, unstructured | Binary protocol |
| Multiplexing | No (pipelining not reliable) | Yes (multiple requests over same connection) |
| Header Compression | No compression | HPACK compression (reduces overhead) |
| Server Push | No | Yes (server can push resources) |
| Request Prioritization | No | Yes (priority tree for resource loading) |
| Frame Types | Not applicable | Headers, Data, Settings, Ping, GoAway, etc. |
| Stream ID | No concept | Each stream has a unique ID |
Example: Enabling HTTP/2 in Nginx
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://backend;
}
}
Key Benefits of HTTP/2
- Better performance through multiplexing and header compression
- Reduced latency with server push capability
- Improved resource loading prioritization
HTTP/1.1 vs HTTP/2
- Performance: HTTP/2 significantly improves page load times
- Efficiency: HTTP/2 reduces overhead with binary framing and compression
- Compatibility: HTTP/2 requires TLS (SSL) support
8. Implementing Server Push Preload
| Directive | Description | Values | Notes |
|---|---|---|---|
| http2_push_preload | Enables or disables server push preload | on | off |
Default: off |
| http2_push_preload_path | Specifies the path to preload | /path/to/resource |
Used in conjunction with http2_push_preload |
| http2_push_preload_header | Specifies headers to include in the push | header-name: header-value |
Optional, can be repeated |
Example: Enabling Server Push Preload
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
http2_push_preload on;
location = / {
root /var/www/html;
index index.html;
http2_push_preload_path /css/style.css;
http2_push_preload_path /js/app.js;
}
}
Note: Server push is an HTTP/2 feature that allows the server to send resources to the client before the client requests them. This can improve page load times by reducing round-trips.
Warning: Misuse of server push can lead to unnecessary resource loading, potentially increasing bandwidth usage and slowing down page load times.
9. Configuring HTTP/2 Idle Timeout
| Directive | Values | Description |
|---|---|---|
| keepalive_timeout | 65s |
Timeout for keep-alive connections in HTTP/2. Default is 65s. |
| keepalive_requests | 100 |
Number of requests allowed per keep-alive connection. Default is 100. |
Example: Setting HTTP/2 Idle Timeout
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
keepalive_timeout 60s;
keepalive_requests 100;
}
Note: The
keepalive_timeout directive controls how long an idle HTTP/2 connection can remain open before being closed by the server. Adjust this value based on your application's needs and expected traffic patterns.
10. Setting HTTP/2 Max Requests
| Directive | Values | Description |
|---|---|---|
| http2_max_requests | 1000 |
Maximum number of requests per HTTP/2 stream before closing the connection |
Example: Configuring max requests
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
http2_max_requests 1000;
}
11. Using HTTP/2 with Proxied Backends
| Directive | Description | Default | Notes |
|---|---|---|---|
| proxy_http_version | Sets the HTTP version for proxy requests | 1.0 | Must be set to 2.0 for HTTP/2 support |
| proxy_set_header | Sets headers to be passed to the backend | None | Use proxy_set_header Upgrade $http_upgrade; for WebSocket support |
| proxy_ssl | Enables SSL for proxy connections | off | Required when proxying to HTTPS backends |
Example: Basic HTTP/2 Proxy Configuration
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass https://backend-server;
proxy_http_version 2.0;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "";
}
}
Note: Ensure that the backend server supports HTTP/2 or is compatible with HTTP/1.1 for graceful degradation.
12. Debugging HTTP/2 Connections
| Command | Description | Notes |
|---|---|---|
| curl --http2 | Enables HTTP/2 for curl requests | Useful for testing HTTP/2 support |
| nghttp -v | Verbose HTTP/2 client for debugging | Shows detailed connection and frame information |
| tcpdump -A | Captures and displays HTTP/2 traffic | Can be used to inspect raw frames |
Note: The
-v flag enables verbose output to show HTTP/2 negotiation and frame details.Warning: Not all versions of curl support HTTP/2 by default. Ensure you're using a version built with nghttp2.