Configure NGINX HTTP/2 server push and connection multiplexing

Advanced 25 min Apr 30, 2026 814 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

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
Note: HTTP/2 server push requires SSL/TLS encryption. If you need help setting up SSL certificates, check out our NGINX SSL certificate automation tutorial.

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

SymptomCauseFix
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

Running this in production?

Want this handled for you? Running this at scale adds a second layer of work: capacity planning, failover drills, cost control, and on-call. See how we run infrastructure like this for European teams.

不想自己管理这些吗?

我们为依赖稳定运行时间的企业管理基础设施。全托管服务,配备一位熟悉您系统架构的固定联系人。

您将拥有一位了解您整体架构的固定联系人

Rotterdam 03:09 · 一条消息即可联系我们,无需填写工单表单