An application can send the same request using HTTP/1.1, HTTP/2, or HTTP/3:
The method, target, headers, status code, and response content keep the same meaning. What changes is how the protocol represents the message, carries concurrent exchanges, establishes a connection, and responds to packet loss.
Those transport differences become visible when a page loads many resources, an API client starts dozens of concurrent calls, or a mobile device moves through a lossy network. HTTP/1.1 often works around limited concurrency with multiple TCP connections. HTTP/2 multiplexes many exchanges over streams in one TCP connection. HTTP/3 retains multiplexing but moves it onto QUIC, where loss on one request stream does not normally stop delivery on unrelated streams.
The newest version is not automatically fastest for every workload. A single slow database query remains slow over all three versions, and a deployment can use HTTP/3 at its public edge while speaking HTTP/1.1 to the application server. The useful question is not merely “Which version is newer?” but “Which limitation does each version remove, and where does that matter in this request path?”
HTTP separates semantics from the way those semantics travel across a network.
The semantics include familiar concepts:
GET, POST, and PUT200, 404, and 503Content-Type, Cache-Control, and ETagHTTP/1.1, HTTP/2, and HTTP/3 all carry these concepts. They differ below that semantic layer:
For HTTPS, HTTP/1.1 and HTTP/2 normally run inside TLS over TCP. HTTP/3 uses QUIC, which integrates TLS 1.3 into its transport handshake. The diagram omits the optional TLS layer on the first two branches to keep the transport comparison readable.
An application framework will often present all three versions through the same request object. The framework reconstructs a logical method, URL, headers, and content regardless of whether the network carried text lines or binary frames.
This is why moving from HTTP/1.1 to HTTP/2 does not require renaming endpoints or changing JSON into a different media type. It changes the protocol mapping, not the resource model.
| Property | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| Standard wire form | Text start-line and header lines; content can be any bytes | Binary frames | Binary frames within QUIC streams |
| Underlying transport | TCP | TCP | QUIC over UDP |
| Concurrent exchanges on one connection | No native multiplexing | Multiplexed HTTP streams | Multiplexed QUIC streams |
| Header compression | None built into the protocol | HPACK | QPACK |
| Effect of one lost transport packet | Blocks later bytes on that TCP connection | Can stall every active stream on that TCP connection | Normally stalls only streams that need the lost data |
| Secure web deployment | Commonly TLS over TCP; cleartext is possible | Commonly TLS over TCP; cleartext prior knowledge is possible | TLS 1.3 protection is integrated and required |
| Common protocol identifier | http/1.1 | h2 | h3 |
The table describes protocol capabilities, not guaranteed performance. A connection can still be limited by bandwidth, server capacity, application dependencies, flow control, or congestion under every version.
Loading simulation...
HTTP/1.1 represents control information with human-readable text:
A response has a textual status line and header section:
“Text protocol” applies to message syntax, not to the content. An HTTP/1.1 response can carry a JPEG, compressed archive, video segment, or any other binary data.
The line-oriented format is convenient for manual inspection, but it requires careful parsing. Recipients must locate line boundaries, interpret fields, and determine where content ends using rules such as Content-Length, chunked transfer coding, or connection closure. Different interpretations of those boundaries can become security problems.
TCP presents one reliable, ordered byte stream. HTTP/1.1 places a sequence of request and response messages on that stream.
Without pipelining, a client sends a request and waits for its response before sending the next request on the same connection:
HTTP/1.1 does define pipelining, in which a client sends several requests without first waiting for their responses:
The server can process safe requests concurrently, but it must return their responses in request order:
If request A takes five seconds while B and C finish immediately, B and C still wait behind A on that connection. This is application-layer head-of-line blocking.
Pipelining also complicates recovery when a connection closes with several requests outstanding. A client must decide which operations are safe to replay and cannot assume that every unanswered request went unprocessed. As a result, general-purpose clients have rarely relied heavily on pipelining.
Clients commonly open multiple TCP connections to the same server:
Now a slow response on connection 1 does not directly prevent response B from arriving on connection 2.
The workaround has costs. Each connection consumes client and server state, performs its own congestion control, and might require a separate TCP and TLS setup. Several new connections also compete independently for network capacity.
HTTP/1.1 does not mandate a universal connection-count limit. Clients choose a conservative limit based on their environment.
HTTP/1.1 remains broadly interoperable and is easy to support in servers, proxies, command-line tools, and constrained environments. It can perform well when:
A protocol should be judged against the workload. Replacing HTTP/1.1 cannot fix a slow query, an oversized response, or a connection that is unnecessarily closed after every request.
HTTP/2 keeps HTTP semantics but replaces text message framing with binary frames. Each request-response exchange belongs to a numbered stream.
A simplified connection might interleave these frames:
The stream identifier lets the receiver put each frame into the correct logical exchange. Frames from streams 1, 3, and 5 can share one connection without confusing their content.
Binary frames are not human-readable in a raw terminal, but they are faster and less ambiguous for software to parse. They also do not imply that application content has become binary. The same JSON bytes can be carried in HTTP/1.1 content or HTTP/2 DATA frames.
HTTP/2 removes HTTP/1.1 response ordering across requests. If stream 1 is waiting on a slow database query, the server can continue sending the response for stream 3.
Streams also fail independently in many application-level situations. A client can cancel one exchange without closing every other exchange on the connection. Per-stream and connection-level flow control prevent a sender from overwhelming a receiver.
Multiplexing usually allows one connection to carry the work that required several HTTP/1.1 connections:
This reduces connection setup overhead and lets the traffic share one congestion-control state.
Requests to the same origin repeat many fields:
HTTP/2 uses HPACK to encode field sections efficiently. It can represent common or previously transmitted names and values by index rather than sending their full text each time.
This is especially useful for many small requests, where uncompressed headers could be large relative to the content. HPACK is stateful within the connection, so a field block that references dynamic entries cannot be decoded without the relevant connection context.
Compression applies to HTTP fields, not to response content. Content-Encoding: gzip or Brotli compression remains a separate decision.
HTTP/2 streams are logically independent, but TCP does not know about them. TCP sees one ordered sequence of bytes.
Suppose one TCP segment contains part of stream 1 and is lost. Later segments might contain complete frames for streams 3 and 5, but TCP cannot deliver those later bytes to HTTP/2 until it recovers the missing segment. All active HTTP/2 streams on that connection can pause.
This is transport-layer head-of-line blocking:
HTTP/2 solved ordering between HTTP responses, but using one ordered TCP connection exposed all multiplexed streams to a shared transport stall.
For an HTTPS URL, the client and server usually select HTTP/2 during the TLS handshake using Application-Layer Protocol Negotiation, or ALPN. The client offers supported identifiers, often including:
The server selects one. If it selects h2, both endpoints start HTTP/2 after the TLS handshake. If it selects http/1.1, they use HTTP/1.1 without changing the URL.
HTTP/2 can technically run over cleartext TCP when the client has prior knowledge that the server supports it. The older h2c HTTP Upgrade mechanism is deprecated and was never widely deployed. For ordinary browser traffic, HTTP/2 effectively means h2 over TLS.
HTTP/2 also defines optional server push, but it is not required for multiplexing or field compression. A system should not make its performance depend on clients accepting speculative pushes.
HTTP/3 moves HTTP semantics onto QUIC, a secure transport carried in UDP datagrams.
That description can be misleading if reduced to “HTTP over UDP.” UDP itself does not provide reliable delivery, ordering, congestion control, encryption, or streams. QUIC implements those capabilities above UDP:
Applications still receive reliable HTTP requests and responses. They do not need to reconstruct missing UDP datagrams.
Each ordinary HTTP/3 request-response exchange uses one client-initiated bidirectional QUIC stream. HTTP/3 places HEADERS and DATA frames within that stream:
Delivery is ordered within an individual stream, but independent across streams. If a packet containing data for stream 0 is lost, stream 0 waits for recovery. Data already available for streams 4 and 8 can continue to the application.
QUIC still applies congestion control across the connection. Packet loss can reduce the sending rate available to all streams, and connection-level control data can affect the whole connection. The improvement is more precise: unrelated request streams do not normally have to wait merely because an earlier byte from another stream is missing.
HTTP/3 uses QPACK for field compression. It serves the same broad purpose as HPACK but is designed for QUIC streams that can arrive independently.
QPACK separates updates to its dynamic table from request streams. An encoder can choose literal or static-table representations that never wait for dynamic state, or it can reference dynamic entries for better compression. A dynamic reference can still block a field section until the corresponding table update arrives, so QPACK reduces compression-related blocking rather than making it impossible.
The internal table and instruction details are not required to understand the comparison:
HTTP/3 relies on QUIC's TLS 1.3 handshake. There is no ordinary cleartext HTTP/3 mode corresponding to cleartext HTTP/1.1.
QUIC does not simply put normal TLS records inside UDP datagrams. TLS handshake messages establish keys, while QUIC protects its own packets and takes responsibility for the transport functions normally surrounding TLS over TCP.
On a repeat connection, a client and server can sometimes use 0-RTT and send early application data based on previously established state. Early data can be replayed by an attacker, so it is unsuitable for an operation that could cause an unwanted repeated effect unless the application has an explicit replay-safety design. HTTP/3 does not make every first request zero-latency, and a server can reject 0-RTT.
TCP identifies a connection using endpoint IP addresses and ports. When a phone moves from Wi-Fi to a cellular network, that tuple changes and the TCP connection normally cannot continue.
QUIC uses connection identifiers that are not tied solely to the network tuple. A client can probe and validate a new path, then continue an existing connection when policy and network conditions permit.
Migration can avoid throwing away active streams and connection state during a network change. It is not teleportation: the new path must be validated, congestion state can change, and an implementation or peer can disable active migration.
The phrase head-of-line blocking is incomplete unless it says which layer is blocked.
In HTTP/1.1 pipelining, response B waits because HTTP requires response A to appear first on that connection. Multiple TCP connections can isolate this wait.
In HTTP/2, the HTTP layer can interleave streams, but a gap in TCP's ordered byte stream temporarily prevents delivery of later bytes for all streams on that connection.
In HTTP/3, QUIC performs reliable ordering separately within streams. A gap in stream 0 does not create a byte-delivery gap inside stream 4.
HTTP/3 has not eliminated every dependency. A page can still need HTML before it knows which resource to request, a server can still serialize database work, connection-level congestion still affects total throughput, and QPACK can introduce limited blocking. It specifically removes the TCP-wide delivery dependency between unrelated request streams.
The URL normally does not contain an HTTP version:
The same URL can be retrieved through HTTP/1.1, HTTP/2, or HTTP/3. Selection happens through connection setup and protocol discovery.
For HTTPS over TCP, the client uses ALPN during the TLS handshake. A capable client can offer both h2 and http/1.1; the server selects one that it supports.
This avoids an extra HTTP round trip and prevents the two endpoints from disagreeing about whether the bytes after TLS follow HTTP/1.1 or HTTP/2 framing.
HTTP/3 uses a different transport, so an existing TCP connection cannot simply switch its remaining bytes to QUIC.
An origin can advertise an HTTP/3 alternative in a response:
This tells the client that the same origin is available using h3 on UDP port 443 and that the advertisement can be remembered for 86,400 seconds. It does not redirect the resource or change the browser's URL.
A client still verifies that the HTTP/3 endpoint is authoritative for the original HTTPS origin, including validating its certificate. An alternative service is a transport destination, not a transfer of trust to an arbitrary server.
A capable client can also learn HTTP/3 availability through other mechanisms, including configuration or DNS service information. Once it knows an HTTP/3 endpoint, it opens a QUIC connection and negotiates the h3 application protocol.
A first visit can therefore use HTTP/2, receive Alt-Svc, and use HTTP/3 on a later connection. A client that already remembers the advertisement can try HTTP/3 immediately.
If UDP is blocked or the QUIC attempt fails, the client should fall back to a TCP-based HTTP version. A production deployment should keep that fallback healthy rather than assuming every network permits UDP traffic.
Protocol negotiation chooses a version for one connection. A client can have an HTTP/3 connection to one origin and HTTP/2 to another. It can also fall back after a network change or failure.
The server cannot force a client to use a version the client does not implement. Advertising HTTP/3 offers an option; it does not remove HTTP/2 or HTTP/1.1 support.
Connection setup contributes latency before a new client and server can exchange an application response.
For a typical new HTTPS connection:
QUIC combines transport establishment and cryptographic negotiation more tightly than TCP followed by TLS. That can reduce setup latency, especially for a client that has communicated with the server before.
Actual timing depends on the TLS version, session resumption, address validation, packet loss, client knowledge, and implementation. An HTTP/3 client that must first learn about the endpoint might not improve the first visit. A failed QUIC attempt followed by fallback can even add delay unless the client races or schedules attempts carefully.
Connection reuse often matters more than small differences in initial setup. A request placed on an already established HTTP/2 or HTTP/3 connection avoids creating another transport and cryptographic session.
Header compression is easy to describe as a simple feature checklist:
The operational consequence is more important. A request with 800 bytes of logical fields does not necessarily consume 800 bytes on an established HTTP/2 or HTTP/3 connection. Repeated names and values can be represented compactly using connection-specific state.
That also means compressed wire size cannot be inferred from application logs. A log might show complete reconstructed fields, while the network carried mostly indexes.
Compression state belongs to one connection. A new connection starts with new dynamic state, so repeatedly replacing connections loses some compression benefit. Intermediaries terminate one connection and create another with independent state; they decode fields on one side and encode them again on the other.
Sensitive fields require careful compression implementation because compressed sizes can reveal information when attacker-controlled input and secrets share a compression context. HPACK and QPACK include controls around indexing, but applications should still avoid placing secrets into unnecessarily variable, attacker-influenced fields.
Often, very little application code changes. A route can receive the same method, fields, and content under all three versions:
The handler returns the same logical response:
The server or proxy performs the protocol-specific encoding.
There are still practical differences:
Connection, Keep-Alive, Transfer-Encoding, and Upgrade cannot be copied into HTTP/2 or HTTP/3.An application should use its server framework's logical HTTP interface rather than attempting to write HTTP/2 frames or QUIC packets itself.
The protocol shown in a browser is only the browser's connection to its immediate peer.
The CDN terminates the QUIC connection, reconstructs the HTTP request, applies its policies, and creates a separate upstream request. The gateway can perform another translation before the application sees it.
The message semantics should survive, but connection-level details do not:
This distinction matters during diagnosis. Enabling HTTP/3 at the CDN improves the client-to-edge segment; it does not prove that the edge-to-origin segment is multiplexed or healthy. Conversely, an application log showing HTTP/1.1 does not prove the user's browser used HTTP/1.1.
Observability should record the downstream and upstream versions separately at each proxy that terminates a connection.
HTTP/2 tends to provide a clear advantage over HTTP/1.1 when many requests share an origin. Web pages with numerous resources and APIs with concurrent calls benefit from multiplexing and field compression without opening a collection of TCP connections.
HTTP/3 is especially attractive when packet loss, changing network paths, or connection setup latency matters. Mobile and long-distance networks can benefit because a lost packet for one request does not normally stop unrelated streams, and a validated migration can retain a connection across a path change.
HTTP/1.1 can remain entirely adequate for a small number of requests on a reused connection, an internal service with simple traffic, or a compatibility path. Its universality also makes it an important fallback.
Suppose a request spends:
Changing the HTTP version can optimize parts of the first 17 milliseconds, but it does not remove the 800-millisecond database wait.
Benefits can also be small when:
HTTP/3 can outperform HTTP/2 under loss and still perform similarly or worse in a different environment. Measure representative devices, networks, request mixes, and connection reuse instead of treating the version number as a performance guarantee.
A practical public service commonly enables several versions:
Supporting HTTP/3 means more than opening UDP port 443 on one machine. Firewalls, load balancers, NAT behavior, rate limits, observability, certificate configuration, and backend routing all need to handle QUIC traffic. A TCP-only health check does not prove that the HTTP/3 path works.
HTTP/2 also needs capacity planning. A single connection can carry many simultaneous streams, so limits should exist for concurrent streams, field-section sizes, flow-control windows, request rates, and expensive backend operations. One client connection should not be able to create unbounded server work.
At a reverse proxy, choose upstream protocol versions deliberately. HTTP/2 between the client and edge does not automatically enable HTTP/2 in the proxy's connection pool to the origin. The ideal choice depends on proxy support, workload concurrency, failure behavior, and operational maturity.
Keep fallbacks observable. If HTTP/3 silently fails on a network and every client falls back successfully, users might see extra setup latency while high-level availability dashboards stay green.
First inspect the curl build:
The feature and protocol list shows whether that build supports HTTP/2 and HTTP/3.
Force HTTP/1.1 and print the version actually used:
Ask curl to negotiate HTTP/2:
For HTTPS, --http2 offers HTTP/2 during TLS negotiation but can use HTTP/1.1 when the server does not select h2. Always read the reported result rather than assuming the requested option won.
If the curl build includes HTTP/3 support, require it with:
Requiring HTTP/3 is useful for diagnosis because it exposes QUIC failure instead of quietly falling back. For user-facing clients, fallback is normally desirable.
Inspect response fields for an HTTP/3 advertisement:
A relevant response can contain:
Absence of Alt-Svc does not prove HTTP/3 is unavailable because a client can learn about it through another mechanism.
Browser network panels commonly have a Protocol column. Values can appear as:
The browser can cache alternative-service information, so two otherwise identical tests might choose different versions. A private profile, cleared network state, or a new hostname can change discovery behavior, but it can also change connection reuse and caching. Record the conditions instead of comparing timings from a single reload.
Record the protocol at each terminated hop:
Also record whether a connection was new or reused, because connection setup can dominate a small request. For HTTP/3 investigations, confirm that UDP reaches the listener and that the certificate and ALPN configuration are valid.
Packet captures alone have limits. HTTPS encrypts HTTP/1.1 and HTTP/2 content, while QUIC encrypts almost all HTTP/3 transport details. Endpoint logs and protocol-aware diagnostics are usually needed to see logical requests and frames.
They do not. Methods, status codes, fields, URLs, and representation formats retain their HTTP meaning. The versions map those semantics to the network differently.
Binary and encrypted describe different properties. HTTP/2 framing is binary even over a cleartext prior-knowledge connection. TLS provides confidentiality. HTTP/3 is encrypted because QUIC integrates TLS 1.3, not merely because its frames are binary.
It removes HTTP/1.1 response-order blocking between streams. It does not remove TCP head-of-line blocking, so one lost TCP segment can stall every stream on the connection.
HTTP/3 avoids TCP-wide delivery blocking between independent request streams. Ordering within a stream, QPACK dependencies, congestion, and application dependencies can still block progress.
QUIC implements reliable per-stream delivery, congestion control, flow control, and security above UDP. Applications do not receive arbitrary unreliable fragments of an HTTP response.
The HTTP/2 specification permits cleartext use with prior knowledge. In normal public browser deployments, HTTP/2 is selected as h2 through ALPN over TLS.
A new QUIC connection still performs a handshake. 0-RTT requires prior state, can be rejected, and carries replay risk. Discovery and fallback can also affect setup time.
The browser only reports its connection to the edge. A CDN or gateway can translate the request to HTTP/2 or HTTP/1.1 on later hops.
Performance depends on request concurrency, network loss, latency, connection reuse, CPU cost, server work, and the complete proxy path. The version is one variable, not a benchmark result.
HTTP/1.1, HTTP/2, and HTTP/3 preserve HTTP semantics but use different wire formats. HTTP/1.1 sends text-delimited messages over TCP, often using several connections for concurrency. Pipelined responses remain ordered, creating application-layer head-of-line blocking.
HTTP/2 adds binary frames, multiplexed streams, and HPACK compression on one TCP connection. Streams progress independently at the HTTP layer, but one lost TCP segment can temporarily stall them all.
HTTP/3 runs over QUIC and UDP. QUIC provides secure, reliable delivery per stream, so one stream's loss normally does not block others. HTTP/3 uses QPACK, integrates TLS 1.3, supports connection migration in some cases, and needs TCP-based fallback when QUIC is unavailable.
Version selection happens per connection through ALPN and alternative-service discovery, and different hops may use different versions; diagnose the complete path rather than the browser alone.
5 quizzes