HTTP/2 isn’t just faster than HTTP/1.1; it’s fundamentally a different protocol that makes multiple requests look like a single, multiplexed stream to the server.

Let’s see it in action. Imagine serving a small HTML page with a few CSS and JS files.

<!DOCTYPE html>
<html>
<head>
    <title>HTTP/2 Test</title>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
</head>
<body>
    <h1>Hello HTTP/2!</h1>
</body>
</html>

With HTTP/1.1, your browser would typically open several connections (up to 6 per host, depending on the browser) and request style.css and script.js sequentially on each connection. Each request involves overhead: establishing the connection, sending headers, waiting for a response.

With HTTP/2, after an initial TLS handshake (which is also optimized with ALPN), your browser can establish one connection and send all those requests (/, style.css, script.js) over that single connection concurrently. The server, using mod_http2, can then process these requests in parallel, sending back the responses as frames on the same stream. This eliminates head-of-line blocking at the HTTP level and significantly reduces latency.

To enable this, you’ll need Apache 2.4.17 or later with mod_http2 compiled in.

First, ensure mod_http2 is enabled. You can check this with apachectl -M or httpd -M. Look for http2_module. If it’s not there, you’ll need to enable it. On Debian/Ubuntu systems, this is often done by:

sudo a2enmod http2
sudo systemctl restart apache2

On RHEL/CentOS systems, you might need to uncomment a LoadModule directive in your httpd.conf or a conf.d file:

LoadModule http2_module modules/mod_http2.so

Then, restart Apache:

sudo systemctl restart httpd

The crucial part is configuring mod_http2 to actually use HTTP/2. This is done within your VirtualHost configuration, typically in your SSL VirtualHost because HTTP/2 is almost universally used over TLS.

Here’s a common setup for an SSL VirtualHost:

<VirtualHost *:443>
    ServerName yourdomain.com
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/yourdomain.com.crt
    SSLCertificateKeyFile /etc/ssl/private/yourdomain.com.key

    # Enable HTTP/2
    Protocols h2 http/1.1

    DocumentRoot /var/www/yourdomain.com/html
    <Directory /var/www/yourdomain.com/html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/yourdomain.com_error.log
    CustomLog ${APACHE_LOG_DIR}/yourdomain.com_access.log combined
</VirtualHost>

The key directive here is Protocols h2 http/1.1. This tells Apache to advertise that it supports both HTTP/2 (h2) and HTTP/1.1. The browser will then negotiate the highest common protocol, which, if supported by the client and the server’s configuration, will be HTTP/2. The order matters: placing h2 first indicates a preference.

You’ll need to restart Apache after making these changes for them to take effect.

To verify it’s working, you can use your browser’s developer tools. Open your site (e.g., https://yourdomain.com), go to the Network tab, and refresh the page. You should see a "Protocol" column (you might need to add it by right-clicking the column headers). If it says "h2" or "HTTP/2", you’re golden.

The Protocols directive can also be set at the server level or within other contexts, but it’s most common and effective within the SSL VirtualHost. This allows you to run HTTP/1.1 on non-SSL ports if you choose, while enforcing HTTP/2 for secure traffic.

One subtle point is that mod_http2 doesn’t just magically make everything faster. It provides the mechanism for multiplexing and header compression (HPACK). The actual performance gains come from how efficiently your application and server can handle concurrent requests on a single connection. If your application logic still serializes operations in a way that blocks other requests, you won’t see the full benefit.

The next thing you’ll likely encounter is optimizing header compression with H2Direct or understanding how server push works.

Want structured learning?

Take the full Http2 course →