Configure NGINX HTTP/2 server push and connection multiplexing to reduce page load times by up to 50% through proactive resource delivery and efficient connection reuse for high-performance web applications.
Prerequisites
- NGINX 1.18+ with HTTP/2 support
- SSL/TLS certificates configured
- Root or sudo access
What this solves
HTTP/2 server push and connection multiplexing eliminate the need for multiple TCP connections and reduce round-trip times by proactively sending resources to clients. This configuration optimizes NGINX to deliver CSS, JavaScript, and images before the browser requests them, while multiplexing multiple requests over a single connection.
Prerequisites
Before configuring HTTP/2 server push and multiplexing, ensure you have:
- NGINX 1.18+ installed with HTTP/2 support
- SSL certificates configured (HTTP/2 requires HTTPS)
- Root or sudo access to the server
- Basic understanding of NGINX configuration
Step-by-step configuration
Verify HTTP/2 support
First, confirm your NGINX installation supports HTTP/2 and check the current version.
nginx -V 2>&1 | grep -o with-http_v2_module
You should see with-http_v2_module in the output. If not, you'll need to recompile NGINX or install a version with HTTP/2 support.
Enable HTTP/2 in server blocks
Edit your main NGINX configuration to enable HTTP/2 on your SSL-enabled virtual hosts.
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# HTTP/2 push configuration
location = /index.html {
http2_push /css/main.css;
http2_push /js/app.js;
http2_push /images/logo.png;
}
root /var/www/html;
index index.html index.htm;
}
Configure HTTP/2 connection multiplexing
Add HTTP/2 specific settings to optimize connection multiplexing and stream handling.
http {
# HTTP/2 connection multiplexing settings
http2_max_concurrent_streams 128;
http2_max_requests 1000;
http2_max_field_size 16k;
http2_max_header_size 32k;
# Enable HTTP/2 server push by default
http2_push_preload on;
# Optimize buffer sizes for HTTP/2
client_body_buffer_size 128k;
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
# Enable gzip compression for HTTP/2
gzip on;
gzip_vary on;
gzip_min_length 10240;
gzip_proxied expired no-cache no-store private must-revalidate auth;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json;
}
Configure automatic server push with preload headers
Set up automatic server push based on Link preload headers sent by your application.
server {
listen 443 ssl http2;
server_name example.com;
# Enable automatic push based on Link headers
http2_push_preload on;
location / {
# Add preload headers for critical resources
add_header Link "; rel=preload; as=style" always;
add_header Link "; rel=preload; as=script" always;
add_header Link "; rel=preload; as=font; crossorigin" always;
try_files $uri $uri/ =404;
}
# Specific push rules for landing page
location = / {
http2_push /css/critical.css;
http2_push /js/critical.js;
http2_push /images/hero.webp;
}
}
Optimize HTTP/2 performance settings
Configure advanced HTTP/2 performance parameters for high-traffic scenarios.
http {
# HTTP/2 performance optimization
http2_recv_buffer_size 256k;
http2_chunk_size 8k;
# Connection keep-alive for HTTP/2
keepalive_timeout 300s;
keepalive_requests 10000;
# Worker process optimization
worker_processes auto;
worker_connections 4096;
worker_rlimit_nofile 8192;
# Enable efficient file serving
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Optimize SSL for HTTP/2
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
}
Configure conditional server push
Set up smart server push that avoids pushing resources already cached by the client.
map $http_cookie $should_push_css {
default 1;
"~*css-cached" 0;
}
map $http_cookie $should_push_js {
default 1;
"~*js-cached" 0;
}
server {
listen 443 ssl http2;
server_name example.com;
location / {
# Conditional push based on cookie presence
if ($should_push_css) {
http2_push /css/main.css;
}
if ($should_push_js) {
http2_push /js/app.js;
}
# Set cache control headers
location ~* \.(css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Set-Cookie "css-cached=1; Path=/; Max-Age=31536000" always;
}
}
}
Test configuration and reload NGINX
Validate your NGINX configuration and apply the changes.
sudo nginx -t
sudo systemctl reload nginx
Verify HTTP/2 server push configuration
Test your HTTP/2 configuration and verify server push is working correctly.
# Check HTTP/2 support
curl -I -H "Accept-Encoding: gzip" --http2 https://example.com/
Test server push with verbose output
curl -v --http2 https://example.com/ 2>&1 | grep -E "(< HTTP/2|< :status|pushed)"
Check HTTP/2 connection multiplexing
for i in {1..5}; do curl -s -w "@curl-format.txt" --http2 https://example.com/ & done; wait
Create a curl format file to measure timing:
time_namelookup: %{time_namelookup}s\n
time_connect: %{time_connect}s\n
time_appconnect: %{time_appconnect}s\n
time_pretransfer: %{time_pretransfer}s\n
time_total: %{time_total}s\n
Monitor HTTP/2 performance
Set up monitoring to track HTTP/2 performance metrics and server push effectiveness.
http {
# Enable detailed logging for HTTP/2
log_format http2_combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time" '
'h2="$http2" push="$http2_pushed"';
access_log /var/log/nginx/access.log http2_combined;
}
Monitor HTTP/2 connections and performance:
# Monitor HTTP/2 connections
sudo ss -tlnp | grep :443
Check NGINX HTTP/2 statistics
sudo tail -f /var/log/nginx/access.log | grep "h2=\"2\""
Monitor server push effectiveness
awk '$NF ~ /push="[1-9]"/ {pushed++} END {print "Pushed resources:", pushed+0}' /var/log/nginx/access.log
For comprehensive performance monitoring, consider integrating with our NGINX Prometheus monitoring setup.
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| HTTP/2 not working | Missing SSL configuration | Enable SSL/TLS with listen 443 ssl http2 |
| Server push not triggering | Incorrect resource paths | Use absolute paths like /css/main.css, not relative |
| High memory usage | Too many concurrent streams | Lower http2_max_concurrent_streams to 64 |
| Connection errors | Buffer size too small | Increase http2_recv_buffer_size to 512k |
| Slow initial page load | Pushing too many resources | Limit to 2-3 critical resources per page |
| Browser compatibility issues | Old SSL configuration | Update to TLSv1.2+ and modern ciphers |
Optimize server push strategies
Implement advanced server push strategies for different content types and user scenarios.
# Different push strategies by content type
location /blog/ {
# Push critical blog assets
http2_push /css/blog.css;
http2_push /js/blog.js;
}
location /shop/ {
# Push e-commerce specific resources
http2_push /css/shop.css;
http2_push /js/cart.js;
http2_push /images/placeholder.svg;
}
Mobile-specific push strategy
map $http_user_agent $is_mobile {
default 0;
"~*Mobile" 1;
}
location / {
if ($is_mobile) {
http2_push /css/mobile.css;
}
if (!$is_mobile) {
http2_push /css/desktop.css;
}
}
Performance testing and benchmarking
Use these tools to measure HTTP/2 server push and multiplexing performance improvements.
# Install HTTP/2 testing tools
sudo apt update
sudo apt install -y curl apache2-utils
Benchmark HTTP/2 vs HTTP/1.1
ab -n 1000 -c 10 -H "Accept-Encoding: gzip" https://example.com/
Test concurrent connections (HTTP/2 multiplexing)
seq 1 10 | xargs -I {} -P 10 curl -s -w "Total: %{time_total}s\n" --http2 https://example.com/
Measure server push effectiveness
curl -v --http2 https://example.com/ 2>&1 | grep -c "< HTTP/2 200 pushed"
Next steps
- Optimize NGINX performance for high-traffic websites
- Configure NGINX rate limiting and DDoS protection
- Configure advanced NGINX caching strategies
- Implement NGINX load balancing with health checks
- Configure NGINX HTTP/3 with performance optimization