HTTP/2 is actually slower to establish a connection than HTTP/1.1, but it wins later.

Let’s see it in action. Imagine we have a simple web server running locally on port 8080 that supports HTTP/2.

# First, let's try to connect using HTTP/1.1 to our local server
curl --http1.1 -v http://localhost:8080/

# Now, let's try to connect using HTTP/2
curl --http2 -v http://localhost:8080/

The -v flag is crucial here. It makes curl verbose, showing us the details of the connection, including the protocol negotiation. When you run the --http2 command, you’ll see output similar to this in the verbose section:

* ALPN, server accepted to use h2
* HTTP/2 over TLS

Or, if you’re connecting over plain HTTP (which requires h2c - HTTP/2 Cleartext):

* HTTP/2 over HTTP/1.1 (h2c)

This output confirms that curl and the server successfully negotiated and agreed to use the HTTP/2 protocol.

The Problem HTTP/2 Solves

HTTP/1.1, for all its ubiquity, suffers from head-of-line blocking. Imagine a single lane highway. If one car stops, every car behind it has to wait, even if their destination is just around the corner. In HTTP/1.1, if a request takes a long time to process, it can block subsequent requests on the same connection, even if those subsequent requests are for completely different resources. Browsers try to mitigate this by opening multiple parallel connections, but each connection has overhead.

HTTP/2 tackles this head-of-line blocking with multiplexing. Think of it as a multi-lane highway where cars can be routed independently. HTTP/2 allows multiple requests and responses to be sent concurrently over a single TCP connection. These requests and responses are broken down into smaller, independent frames. The client and server can then reassemble these frames in the correct order, making the process much more efficient.

Beyond multiplexing, HTTP/2 introduces other performance enhancements:

  • Header Compression (HPACK): HTTP/1.1 headers are repetitive and can add significant overhead. HPACK compresses these headers, reducing the amount of data that needs to be sent.
  • Server Push: Servers can proactively send resources that they anticipate the client will need, rather than waiting for the client to request them. This can reduce latency by eliminating round trips.
  • Stream Prioritization: Clients can indicate the priority of different streams, allowing the server to allocate resources more effectively.

Internal Mechanics and Levers

When you use curl --http2, you’re telling curl to attempt an HTTP/2 connection. The negotiation happens during the TLS handshake (for https://) or immediately after the TCP connection is established (for http:// with h2c).

For TLS connections (HTTPS), the Application-Layer Protocol Negotiation (ALPN) extension is used. During the TLS handshake, curl advertises the protocols it supports (e.g., h2, http/1.1). The server then selects one from the advertised list that it also supports. If h2 is selected, the connection proceeds as HTTP/2. If only http/1.1 is selected, it falls back to HTTP/1.1.

For unencrypted connections (HTTP), the h2c protocol is used. This is less common and often requires explicit server configuration to enable. curl will attempt h2c if you specify --http2 and the connection is not TLS.

The key "levers" you control with curl are:

  • --http1.0, --http1.1, --http2: Explicitly set the protocol version.
  • --no-http1.1: Disable HTTP/1.1 negotiation.
  • --no-http2: Disable HTTP/2 negotiation.

If you don’t specify a protocol, curl will try to negotiate the best available, often preferring HTTP/2 if supported by both client and server. The -v flag is your primary tool for observing this negotiation.

The most surprising thing about HTTP/2’s performance gains is that they aren’t primarily due to lower latency on the wire. In fact, establishing an HTTP/2 connection, especially over TLS, involves a more complex handshake than HTTP/1.1. The real magic happens after the connection is established, with multiplexing and header compression allowing much more efficient use of that single connection, especially in scenarios with many small requests.

The next hurdle you’ll likely encounter is understanding how to leverage Server Push effectively, as it requires careful consideration of what resources to push and when, to avoid sending unnecessary data.

Want structured learning?

Take the full Http2 course →