HTTP/1.1 vs HTTP/2 vs HTTP/3

By Oleksandr Andrushchenko — Published on
0 Likes
0 Dislikes
HTTP/1.1 vs HTTP/2 vs HTTP/3
HTTP/1.1 vs HTTP/2 vs HTTP/3

HTTP/1.1, HTTP/2, and HTTP/3 expose largely the same application-level request and response model, but they move those requests across the network very differently. The differences become important when applications make many concurrent requests, operate over high-latency networks, or experience packet loss.

HTTP/1.1 commonly relies on multiple TCP connections for concurrency. HTTP/2 multiplexes many streams over one TCP connection. HTTP/3 keeps multiplexing but replaces TCP with QUIC over UDP, allowing independent streams to recover from packet loss without TCP-level head-of-line blocking across the entire connection.

For backend engineers, protocol selection is primarily about connection behavior, multiplexing, latency, failure isolation, infrastructure compatibility, and operational complexity rather than differences in REST APIs or HTTP methods.

Table of Contents

HTTP as a Request-Response Protocol

At the application level, HTTP versions share familiar concepts: methods, URLs, headers, status codes, request bodies, and response bodies.

An application can expose the same endpoint regardless of whether the client communicates using HTTP/1.1, HTTP/2, or HTTP/3.

What Remains the Same

A logical request still looks like:

GET /api/shipments/123

Host: api.example.com
Authorization: Bearer ...
Accept: application/json

And the application can still produce:

{
  "id": 123,
  "status": "in_transit",
  "carrier": "carrier-a"
}

Controllers, routing, authentication, caching semantics, and most application code generally do not need separate implementations for each HTTP version.

The major differences exist below these application semantics.

What Changes Between Versions

The versions differ substantially in how requests are represented and transported.

Characteristic HTTP/1.1 HTTP/2 HTTP/3
Primary transport TCP TCP QUIC over UDP
Message representation Text-oriented framing Binary framing Binary framing over QUIC
Multiplexing Limited per connection Multiple streams Multiple independent streams
Header compression No protocol-level equivalent HPACK QPACK
Transport-level head-of-line blocking across streams TCP connection affected Yes Avoided between independent QUIC streams

The biggest architectural progression is therefore:

HTTP/1.1
Multiple connections for concurrency
        |
        v
HTTP/2
Multiple streams over one TCP connection
        |
        v
HTTP/3
Multiple streams over QUIC
with independent stream recovery

HTTP/1.1

HTTP/1.1 remains simple, mature, and broadly supported. Its major limitation for modern workloads is how concurrency interacts with TCP connections.

A single connection processes an ordered sequence of bytes, making concurrent independent request handling less flexible than newer protocols.

Persistent Connections

Reusing TCP connections avoids repeatedly paying connection-establishment costs.

Without connection reuse:

TCP connect
TLS handshake
Request
Response
Close

TCP connect
TLS handshake
Request
Response
Close


With persistent connection:

TCP connect
TLS handshake

Request 1
Response 1

Request 2
Response 2

Request 3
Response 3

Persistent connections are therefore critical for efficient HTTP/1.1 communication.

Backend HTTP clients should normally use connection pools rather than constructing a completely new transport connection for every request.

import httpx

with httpx.Client() as client:
    shipment = client.get(
        "https://api.example.com/shipments/123"
    )

    events = client.get(
        "https://api.example.com/shipments/123/events"
    )

The client can reuse existing connections rather than repeatedly creating them.

Concurrency Limitations

Suppose a client needs four independent resources.

Conceptually, serial use of one connection looks like:

Connection

Request A  ---> Response A
Request B  ---> Response B
Request C  ---> Response C
Request D  ---> Response D

HTTP/1.1 pipelining exists but has historically seen limited practical use, and modern clients commonly achieve concurrency by opening multiple connections.

Connection 1 ---> Request A
Connection 2 ---> Request B
Connection 3 ---> Request C
Connection 4 ---> Request D

This works, but additional connections consume resources across clients, servers, load balancers, proxies, NAT infrastructure, and firewalls.

Advantages:

  • simple and mature
  • extremely broad compatibility
  • easy to inspect and troubleshoot
  • works well for many ordinary backend workloads

Disadvantages:

  • concurrency often requires multiple connections
  • more connection-management overhead
  • repeated headers can add unnecessary bytes
  • less efficient for many concurrent requests

When to Use: HTTP/1.1 remains reasonable when compatibility matters most, request concurrency is limited, or infrastructure does not support newer versions end to end.

HTTP/2

HTTP/2 changes the wire representation of HTTP while preserving application semantics. Requests and responses are divided into binary frames associated with logical streams.

HTTP 1.1 vs HTTP 2
HTTP 1.1 vs HTTP 2

The central improvement is multiplexing.

Streams and Multiplexing

Instead of requiring separate TCP connections for independent concurrent requests, HTTP/2 can interleave frames belonging to multiple streams on one connection.

Single TCP Connection

+--------------------------------------+
| Stream 1 frame                       |
| Stream 3 frame                       |
| Stream 1 frame                       |
| Stream 5 frame                       |
| Stream 3 frame                       |
| Stream 5 frame                       |
+--------------------------------------+

Conceptually:

Client
  |
  |==== one TCP connection =================|
  |                                          |
  +---- Stream 1 ---- GET /shipment --------+
  +---- Stream 3 ---- GET /customer --------+
  +---- Stream 5 ---- GET /tracking --------+
  +---- Stream 7 ---- GET /pricing ---------+
                                             |
                                           Server

One slow HTTP request does not inherently require the application to wait before sending another request on a different stream.

HTTP/2 also compresses HTTP headers using HPACK, which can reduce repeated metadata when many requests share similar headers.

This is useful for APIs where headers such as authorization, content negotiation, cookies, tracing information, and user-agent metadata are repeatedly transmitted.

TCP Head-of-Line Blocking

HTTP/2 solves application-layer request serialization, but all streams still share one ordered TCP byte stream.

Suppose packets carrying data from several HTTP/2 streams are transmitted:

TCP packets

[ A1 ][ B1 ][ C1 ][ A2 ][ B2 ][ C2 ]
               X
            packet lost

TCP must recover missing bytes before later bytes can be delivered in order to the HTTP/2 layer.

As a result, packet loss affecting one portion of the TCP stream can temporarily delay data belonging to otherwise independent HTTP/2 streams.

HTTP/2 streams
     |
     +-- Stream A
     +-- Stream B
     +-- Stream C
     |
     v
Single ordered TCP stream
     |
     X packet loss
     |
     v
Later TCP data waits for recovery

This is transport-level head-of-line blocking.

HTTP/2 therefore removes an important HTTP/1.1 concurrency limitation but cannot remove TCP's ordered-delivery behavior.

Advantages:

  • multiplexes many requests over fewer connections
  • reduces connection proliferation
  • compresses headers
  • works well for high-concurrency APIs
  • broad support across modern infrastructure

Disadvantages:

  • all streams still share TCP transport behavior
  • packet loss can temporarily affect multiple streams
  • binary framing makes raw debugging less human-readable
  • proxies and load balancers must correctly support HTTP/2 behavior

When to Use: HTTP/2 is a strong default for modern APIs and service communication when infrastructure supports it and many concurrent requests benefit from multiplexing.

HTTP/3

HTTP/3 changes the transport foundation. Instead of running HTTP over TCP, it runs over QUIC, which itself runs over UDP.

From HTTP 1 to HTTP 3
From HTTP 1 to HTTP 3

QUIC provides features traditionally associated with transport protocols, including reliable delivery, congestion control, connection management, encryption, and stream multiplexing.

QUIC Transport

The simplified protocol stacks look like:

HTTP/1.1          HTTP/2             HTTP/3

HTTP              HTTP/2             HTTP/3
 |                   |                  |
TLS                 TLS                QUIC
 |                   |                  |
TCP                 TCP                UDP
 |                   |                  |
IP                  IP                 IP

HTTP/3 does not simply send unreliable HTTP requests over UDP. QUIC implements reliable transport semantics above UDP while using a design better suited to multiplexed streams.

QUIC also integrates TLS 1.3 into the transport handshake rather than treating transport establishment and TLS establishment as entirely separate protocol phases.

This can reduce setup latency, particularly when network round-trip time is significant.

Independent Stream Recovery

The major architectural improvement is that loss in one QUIC stream does not require unrelated streams to wait for the missing data.

QUIC Connection

Stream A: [ A1 ][ A2 ][ A3 ]
Stream B: [ B1 ][ X  ][ B3 ]
Stream C: [ C1 ][ C2 ][ C3 ]

                   |
                   v

Stream B waits for B2 recovery

Streams A and C can continue

Reliable ordering still exists inside each stream, but it is not imposed globally across all HTTP streams by one TCP byte stream.

This can improve behavior on networks with packet loss, variable connectivity, or higher latency.

QUIC also supports connection migration. A connection is not identified solely by the traditional IP-address and port tuple in the same way as TCP.

This can help when a client changes network paths, such as moving from Wi-Fi to a mobile network.

Advantages:

  • independent transport streams
  • avoids TCP head-of-line blocking between HTTP streams
  • integrated modern encryption
  • efficient connection establishment
  • better behavior for changing client network paths

Disadvantages:

  • more complex protocol implementation
  • UDP handling can differ across existing network infrastructure
  • observability and troubleshooting tools may require adaptation
  • backend infrastructure may terminate HTTP/3 before forwarding traffic using another HTTP version

When to Use: HTTP/3 is particularly valuable for internet-facing applications serving geographically distributed or mobile clients where latency, packet loss, and network changes matter.

Comparing HTTP Versions

The evolution from HTTP/1.1 to HTTP/3 is largely an attempt to improve concurrency and reduce the cost of network latency without changing the basic HTTP programming model.

Latency and Connection Behavior

Consider a client requesting several independent resources.

HTTP/1.1

TCP 1 ---> Request A
TCP 2 ---> Request B
TCP 3 ---> Request C
TCP 4 ---> Request D


HTTP/2

TCP connection
   |
   +-- Stream A
   +-- Stream B
   +-- Stream C
   +-- Stream D


HTTP/3

QUIC connection
   |
   +-- Independent Stream A
   +-- Independent Stream B
   +-- Independent Stream C
   +-- Independent Stream D

HTTP/2 significantly reduces the need for many parallel TCP connections. HTTP/3 retains that advantage while improving stream isolation during transport-level packet loss.

However, protocol version alone does not determine request latency.

Real performance depends on:

  • network round-trip time
  • packet-loss rate
  • connection reuse
  • request concurrency
  • payload size
  • server processing time
  • load-balancer behavior
  • TLS configuration
  • client implementation
  • connection-pool configuration

An HTTP/1.1 connection reused inside a low-latency private network can outperform a poorly configured HTTP/3 path. Architecture matters more than version numbers alone.

Backend and Infrastructure Trade-Offs

HTTP version selection is also not necessarily end-to-end.

A production request can use different protocol versions on different network segments:

Browser
   |
   | HTTP/3
   v
CDN
   |
   | HTTP/2
   v
Load Balancer
   |
   | HTTP/1.1
   v
Application

This is common because edge infrastructure terminates client connections and establishes separate connections toward backend origins.

Consequently, enabling HTTP/3 at the edge does not automatically mean application servers receive HTTP/3 traffic.

Use Case Typical Choice Reason
Legacy integration HTTP/1.1 Maximum compatibility
Modern internal API HTTP/2 Multiplexing with mature infrastructure support
High-concurrency RPC HTTP/2 Efficient multiple streams
Public web edge HTTP/2 and HTTP/3 Broad compatibility plus modern transport
Mobile internet traffic HTTP/3 when supported Better behavior under loss and network migration

The transport differences between TCP and UDP are covered in TCP vs UDP: Choosing the Right Protocol.

Production Design Example

Consider a global logistics platform serving browser clients, mobile applications, partner APIs, and internal backend services.

The system does not require one HTTP version everywhere. Each network segment can use the protocol that best fits its requirements and infrastructure.

Architecture

Browsers / Mobile Apps
          |
          | HTTP/2 or HTTP/3
          v
     Global CDN / Edge
          |
          | HTTP/2
          v
     Regional Load Balancer
          |
          +-------------------+
          |                   |
          v                   v
     Shipment API         Tracking API
          |                   |
          | HTTP/2            | HTTP/2
          v                   v
     Pricing Service      Carrier Service
          |
          | TCP
          v
      PostgreSQL

The edge supports HTTP/3 for compatible clients while retaining HTTP/2 or HTTP/1.1 compatibility for clients that cannot use it.

The CDN terminates the client connection. Traffic between the CDN and regional load balancer can use HTTP/2 independently of the client-side protocol.

Internal service communication also uses HTTP/2 where multiplexing provides value.

Request and Failure Flow

Suppose a mobile application opens a shipment tracking screen and concurrently requests:

GET /shipments/123
GET /shipments/123/events
GET /shipments/123/documents
GET /shipments/123/carrier
GET /shipments/123/eta

With HTTP/1.1, efficient concurrency commonly requires multiple connections or careful reuse of a connection pool.

With HTTP/2, these requests can become independent streams over one TCP connection:

TCP Connection

Stream 1 ---> shipment
Stream 3 ---> events
Stream 5 ---> documents
Stream 7 ---> carrier
Stream 9 ---> ETA

Now suppose packet loss occurs on the mobile network.

HTTP/2
   |
   v
TCP packet lost
   |
   v
TCP waits for missing bytes
   |
   v
Multiple HTTP streams can be delayed

With HTTP/3:

HTTP/3
   |
   v
QUIC packet carrying Stream 5 data lost
   |
   +---- Stream 5 waits for recovery
   |
   +---- Stream 1 continues
   +---- Stream 3 continues
   +---- Stream 7 continues
   +---- Stream 9 continues

This does not make HTTP/3 immune to congestion or packet loss. Lost data still needs recovery when reliable delivery is required. The improvement is that loss associated with one stream does not impose TCP's connection-wide ordered-delivery blocking on unrelated streams.

Production monitoring should distinguish client-facing and origin-facing protocol behavior.

Useful metrics include:

  • requests by HTTP version
  • connection establishment latency
  • connection reuse rate
  • active connections
  • requests per connection
  • concurrent streams
  • TLS handshake latency
  • request latency by protocol version
  • connection resets
  • TCP retransmissions
  • QUIC connection failures
  • HTTP/3 fallback rate
  • edge-to-origin latency

Comparing HTTP versions without separating network conditions can produce misleading conclusions. Mobile users experiencing packet loss and internal services operating inside one data center have fundamentally different network environments.

Common Mistakes

HTTP upgrades can improve network efficiency, but protocol versions do not fix inefficient application architecture. Excessive requests, poor connection reuse, slow dependencies, and incorrect timeout policies remain problems regardless of the HTTP version.

Mistake Production Impact Better Approach
Opening a new HTTP/1.1 connection per request Repeated connection and TLS setup increases latency. Use persistent connections and pooling.
Assuming HTTP/2 uses one request at a time Multiplexing benefits are overlooked. Understand HTTP/2 streams and concurrency.
Assuming HTTP/2 eliminates all head-of-line blocking TCP packet loss can still delay multiple streams. Distinguish HTTP-layer multiplexing from TCP ordering.
Assuming HTTP/3 is unreliable because it uses UDP QUIC's reliability model is misunderstood. Treat QUIC as a reliable transport implemented over UDP.
Assuming HTTP/3 is always faster Complexity is added without measurable benefit. Benchmark under representative network conditions.
Assuming one HTTP version exists end to end Debugging targets the wrong network segment. Observe protocols separately at each hop.
Ignoring connection reuse Handshake costs dominate short requests. Monitor and tune persistent connections.
Using excessive parallel HTTP/1.1 connections Connection capacity is wasted across infrastructure. Bound pools or use multiplexed protocols.
Upgrading protocol without measuring performance No evidence exists that the change improves production behavior. Measure latency, loss, connections, and resource usage.
Expecting HTTP upgrades to fix slow application code Database and service bottlenecks remain unchanged. Profile the complete request path.

Production Checklist

HTTP protocol decisions should be made from observed traffic patterns and network conditions rather than version numbers alone.

  • Enable persistent connections. Avoid unnecessary transport and TLS handshakes.
  • Reuse HTTP clients. Maintain connection pools instead of constructing clients per request.
  • Measure request concurrency. Determine whether multiplexing provides meaningful value.
  • Prefer HTTP/2 for concurrent modern APIs. Use multiplexing when infrastructure supports it reliably.
  • Evaluate HTTP/3 at internet-facing edges. Test workloads exposed to latency, packet loss, and changing networks.
  • Retain protocol fallback. Do not assume every client or network path supports HTTP/3.
  • Inspect every network segment. Client-to-edge and edge-to-origin connections may use different protocols.
  • Monitor connection reuse. Poor reuse can eliminate expected protocol benefits.
  • Monitor connections and streams. Understand concurrency at both transport and application layers.
  • Measure handshake latency. Connection setup becomes important for short-lived traffic.
  • Track protocol distribution. Know what percentage of production traffic actually uses each HTTP version.
  • Track fallback behavior. HTTP/3 failures may silently fall back to another protocol.
  • Test packet loss. Compare protocol behavior under realistic degraded networks.
  • Test high round-trip latency. Geographic distance changes handshake and request costs.
  • Configure explicit timeouts. Protocol improvements do not replace bounded waiting.
  • Protect backend capacity. Multiplexing can increase request concurrency toward downstream services.
  • Benchmark complete request paths. Include proxies, TLS, load balancers, and application processing.
  • Separate transport from application performance. Diagnose database and service latency independently of HTTP behavior.

Conclusion

HTTP/1.1, HTTP/2, and HTTP/3 preserve the same fundamental HTTP request-response model while progressively changing how concurrent communication is transported.

HTTP/1.1 relies heavily on connection reuse and often multiple connections for concurrency. HTTP/2 introduces multiplexed streams over TCP. HTTP/3 moves those streams to QUIC, allowing transport recovery to occur independently across streams and improving behavior on lossy or changing networks.

Key Takeaway: HTTP/2 is a strong choice for efficient multiplexed communication across modern infrastructure, while HTTP/3 provides additional benefits for latency-sensitive and unreliable network paths. The best protocol is the one that improves measured production behavior without introducing unnecessary operational complexity.

Author

Enjoyed this article?

Support Oleksandr Andrushchenko

Buy me a coffee

This helps Oleksandr Andrushchenko continue creating useful content

Comments (0)