Protocol-level differences explain performance results, proxy problems and bugs that only appear on one HTTP version.
For https:// URLs, a curl built with nghttp2 offers HTTP/2 during the TLS handshake via ALPN, and uses it if the server agrees; otherwise it falls back to HTTP/1.1. -w '%{http_version}' reports what was actually used.
Forcing versions for testing:
--http1.1disables HTTP/2 negotiation, useful when a proxy or server misbehaves with h2.--http2-prior-knowledgespeaks HTTP/2 over plainhttp://without upgrade (h2c), as used by some gRPC backends.--http3tries HTTP/3 over QUIC (UDP) and falls back to older versions if it fails;--http3-onlydoes not fall back. Both require a curl built with HTTP/3 support (check theHTTP3feature incurl -V).
Browsers discover HTTP/3 through the Alt-Svc response header. curl can do the same: --alt-svc cache.txt stores those headers and uses HTTP/3 on later requests.
Within one curl invocation, connections are kept and reused for later URLs to the same host; with HTTP/2 multiple parallel transfers (-Z) are multiplexed as streams over one connection. %{num_connects} shows how many new connections were made.
Head-of-line blocking is the reason HTTP/3 exists: in HTTP/2 a lost TCP packet stalls every stream, while QUIC streams are independent. Compare versions on a lossy link with -w '%{time_total}' to see it.
Example
curl -sS -o /dev/null -w '%{http_version}\n' https://www.google.com # 2
curl -sS --http1.1 -o /dev/null -w '%{http_version}\n' https://www.google.com # 1.1
curl -V | grep -o 'HTTP3' # is HTTP/3 compiled in?
curl -sS --http3 -o /dev/null -w '%{http_version}\n' https://cloudflare.com # 3
curl -sS --http2-prior-knowledge http://localhost:50051/ # h2c, no TLS
curl -sSI https://cloudflare.com | grep -i alt-svc
# alt-svc: h3=":443"; ma=86400
curl -sS -o /dev/null -o /dev/null -w '%{num_connects} ' \
https://example.com/ https://example.com/about # 1 0 (second reused)Remember
- HTTPS negotiates HTTP/2 via ALPN; -w %{http_version} shows the result
- --http1.1, --http2-prior-knowledge, --http3, --http3-only force versions
- Connections are reused within one invocation; Alt-Svc advertises HTTP/3
Watch out for
- Assuming --http3 works everywhere; many distro builds lack HTTP/3 support.