AlgoMaster Logo

HTTP/1.1 vs HTTP/2 vs HTTP/3

High Priority34 min readUpdated August 14, 2026
Listen to this chapter
Unlock Audio

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?”

One Set of Semantics, Three Wire Mappings

HTTP separates semantics from the way those semantics travel across a network.

The semantics include familiar concepts:

  • Request methods such as GET, POST, and PUT
  • Status codes such as 200, 404, and 503
  • Header fields such as Content-Type, Cache-Control, and ETag
  • Request and response content
  • Caching, authentication, conditional requests, and range requests

HTTP/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.

The Versions at a Glance

PropertyHTTP/1.1HTTP/2HTTP/3
Standard wire formText start-line and header lines; content can be any bytesBinary framesBinary frames within QUIC streams
Underlying transportTCPTCPQUIC over UDP
Concurrent exchanges on one connectionNo native multiplexingMultiplexed HTTP streamsMultiplexed QUIC streams
Header compressionNone built into the protocolHPACKQPACK
Effect of one lost transport packetBlocks later bytes on that TCP connectionCan stall every active stream on that TCP connectionNormally stalls only streams that need the lost data
Secure web deploymentCommonly TLS over TCP; cleartext is possibleCommonly TLS over TCP; cleartext prior knowledge is possibleTLS 1.3 protection is integrated and required
Common protocol identifierhttp/1.1h2h3

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: Text Messages over TCP

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.

One Ordered Sequence per Connection

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.

Parallel Connections as a Workaround

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.

Where HTTP/1.1 Still Fits

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 client makes only one or a few requests
  • Connections are reused rather than repeatedly created
  • The application is dominated by server processing or a large transfer
  • An older intermediary does not support a newer version

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: Multiplexed Streams over One TCP Connection

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.

Independent HTTP Streams

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.

HPACK Header Compression

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.

The Remaining TCP Head-of-Line Problem

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.

Starting HTTP/2

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: HTTP over QUIC

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:

  • Reliable delivery within each stream
  • Multiplexed bidirectional and unidirectional streams
  • Per-stream and connection-level flow control
  • Loss detection and congestion control
  • TLS 1.3-based confidentiality, integrity, and peer authentication
  • Connection identifiers that can support a validated network-path change

Applications still receive reliable HTTP requests and responses. They do not need to reconstruct missing UDP datagrams.

One Request per QUIC Stream

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.

QPACK Header Compression

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:

Encryption Is Part of QUIC

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.

Connection Migration

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.

Three Forms of Head-of-Line Blocking

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.

How a Client Selects a Version

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.

Selecting HTTP/1.1 or HTTP/2

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.

Discovering HTTP/3

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.

Negotiation Is per Connection

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.

Secure Connection Setup

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 and State

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.

What Changes for an Application Developer?

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:

  • HTTP/2 and HTTP/3 field names arrive lowercase at the protocol layer.
  • Connection-specific HTTP/1.1 fields such as Connection, Keep-Alive, Transfer-Encoding, and Upgrade cannot be copied into HTTP/2 or HTTP/3.
  • Request concurrency can be much higher on one HTTP/2 or HTTP/3 connection, exposing application pool limits that were previously hidden by fewer in-flight requests.
  • A canceled stream should cancel unnecessary backend work when possible, rather than leaving an expensive operation running.
  • Per-connection assumptions become risky because one connection can carry many users' logical requests through a proxy.

An application should use its server framework's logical HTTP interface rather than attempting to write HTTP/2 frames or QUIC packets itself.

One Request Path Can Use Several Versions

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.

When Each Version Helps

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.

When a Higher Version Might Not Be Faster

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:

  • The workload has one request at a time
  • A transfer is limited mainly by available bandwidth
  • The network has low latency and almost no loss
  • A proxy converts the connection to a less capable upstream version
  • QUIC is blocked and the client must fall back
  • The implementation's CPU, memory, or configuration becomes the bottleneck

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.

Deployment Considerations

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.

Inspecting the Negotiated Version

Using curl

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.

Using Browser Developer Tools

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.

At Proxies and Servers

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.

Common Misunderstandings

“HTTP/2 and HTTP/3 change REST or API semantics”

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 framing means the content is encrypted”

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.

“HTTP/2 removes head-of-line blocking”

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 has no head-of-line blocking”

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.

“HTTP/3 trades reliability for speed because it uses UDP”

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.

“HTTP/2 always requires TLS”

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.

“HTTP/3 is always a zero-round-trip protocol”

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.

“If the browser shows h3, the application received HTTP/3”

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.

“The highest available version must be the fastest”

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.

Summary

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.

Quiz

HTTP/1.1 vs HTTP/2 vs HTTP/3 Quiz

5 quizzes