Blog/HTTP/3 and QUIC: The New Network Foundations
networkinghttp3quicperformance

HTTP/3 and QUIC: The New Network Foundations

March 15, 2026·12 min read·by Bishwambhar Sen
A packet stream diagram contrasting single-stream TCP serialization with multi-stream multiplexing over a UDP-based QUIC connection.
Executive Briefing & Key Constraints

HTTP/3 replaces TCP with QUIC, a UDP-based protocol that eliminates head-of-line blocking and accelerates connection establishment. We unpack how QUIC redefines L4/L7 performance.

Target AudienceSenior Software Engineers, Systems & Cloud Architects
Topic Classificationnetworking, http3, quic, performance

Concept

For nearly three decades, the Hypertext Transfer Protocol (HTTP) relied on the Transmission Control Protocol (TCP) for reliable transport. While HTTP/1.1 and HTTP/2 introduced major optimizations—such as persistent connections and multiplexed streams—they remained bound by the fundamental limitations of TCP.

HTTP/3 fundamentally disrupts this paradigm. It replaces TCP with QUIC (Quick UDP Internet Connections), a new transport-layer protocol developed initially by Google and standardized by the IETF in RFC 9000. Operating over the User Datagram Protocol (UDP), QUIC redesigns connection establishment, packet loss handling, and security, creating a faster, more resilient foundation for web traffic.

Solving Head-of-Line (HOL) Blocking

In HTTP/2, multiple request/response streams are multiplexed over a single TCP connection. This solves the HTTP/1.1 browser limit of six concurrent connections. However, multiplexing introduces Transport-Layer Head-of-Line (HOL) Blocking.

Because TCP is a byte-stream protocol, it has no concept of individual HTTP streams. If a single IP packet containing data for Stream A is lost in transit, TCP halts the delivery of all packets (including those for Stream B and Stream C) until the lost packet is retransmitted and acknowledged. A single dropped packet degrades the throughput of the entire connection.

QUIC solves this by moving stream multiplexing from the application layer (L7) down to the transport layer (L4). In QUIC, each stream is treated as an independent channel. If a packet belonging to Stream A is dropped, only Stream A is blocked waiting for retransmission. Packets for Stream B and Stream C continue to be processed by the application immediately, isolating the blast radius of packet loss.


Constraints

Transitioning to HTTP/3 and QUIC requires resolving physical, network, and operational constraints:

1. Middlebox Interference and UDP Blocking

Historically, internet firewalls, routers, and load balancers (middleboxes) have been optimized for TCP and UDP DNS traffic. Many enterprise networks and public Wi-Fi providers actively block or throttle non-DNS UDP traffic to prevent DDoS amplification attacks. To ensure reliability, services deploying HTTP/3 must support Graceful Fallback. The client initially connects via HTTP/2 or HTTP/1.1 over TCP. The server then responds with an Alt-Svc (Alternative Services) HTTP header, informing the client that HTTP/3 is available on a specific UDP port:

Alt-Svc: h3=":443"; ma=86400

Subsequent requests from the client will attempt to use QUIC, falling back to TCP if the UDP handshake fails.

2. User-Space CPU Overhead

Unlike TCP, which has been baked into operating system kernels and network interface cards (NICs) via TCP Offload Engines (TOE) for decades, QUIC is implemented in user-space. Encrypting, decrypting, and parsing individual UDP datagrams in user-space requires frequent context switches, consuming significantly more CPU (often 2x to 3x) than TCP for equivalent throughput. Mitigating this requires specialized kernel interfaces (like io_uring on Linux) and advanced UDP socket optimizations (like UDP Receive Segment Coalescing).

3. Integrated Encryption (TLS 1.3 Mandate)

QUIC does not run TLS as an independent layer on top of transport (like TCP/TLS). Instead, QUIC incorporates TLS 1.3 directly into its handshake protocol. Every QUIC packet—except the initial client hello—is fully encrypted, including the packet headers (such as sequence numbers). While this prevents snooping and tempering by middleboxes, it makes debugging network packets (via tools like Wireshark) more complex, requiring access to TLS key logs.


Trade-offs

Zero-RTT Replay Attacks vs. Latency reduction

QUIC supports 0-RTT (Zero Round-Trip Time) connection establishment. When a client reconnects to a server, it can send encrypted application data (like an HTTP GET request) inside the very first packet, using pre-shared cryptographic keys from the previous session. While this eliminates connection latency, it exposes the server to Replay Attacks. An attacker can capture the initial 0-RTT packet and resend it multiple times to the server. If the request triggers a side effect (such as processing a payment or modifying state), the server may execute the operation multiple times. Therefore, 0-RTT should only be enabled for idempotent read requests (GET/HEAD).

Connection Migration vs. Client Tracking

QUIC connections are identified by a unique 64-bit Connection ID (CID) rather than the traditional 4-tuple (source IP, source port, destination IP, destination port). If a user switches from Wi-Fi to cellular data, their IP address changes, but the QUIC connection migrates seamlessly because the CID remains the same. While this prevents connection drops during transitions, persistent CIDs could allow third parties to track users across different networks. To balance mobility and privacy, QUIC servers and clients dynamically negotiate and rotate Connection IDs during a session.


Code

The following example shows how to configure an ASP.NET Core Kestrel web server to support HTTP/3 and QUIC.

First, we configure Kestrel in Program.cs to listen on port 443, enabling HTTP/1, HTTP/2, and HTTP/3 protocols, and register the necessary middleware to add the Alt-Svc header to outgoing responses:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Net;

var builder = WebApplication.CreateBuilder(args);

// Configure Kestrel to support HTTP/3 and QUIC
builder.WebHost.ConfigureKestrel(options =>
{
    options.Listen(IPAddress.Any, 443, listenOptions =>
    {
        // Require HTTPS (QUIC mandates encryption)
        listenOptions.UseHttps();
        
        // Enable protocols including HTTP/3
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
    });
});

builder.Services.AddControllers();

var app = builder.Build();

// Middleware to inject Alt-Svc headers for HTTP/3 discovery
app.Use(async (context, next) =>
{
    // Inform clients that HTTP/3 is available on port 443
    context.Response.Headers.Add("Alt-Svc", "h3=\":443\"; ma=86400");
    await next();
});

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

Handshake Lifecycle Comparison

The diagram below compares the connection establishment sequences of TCP + TLS 1.3 versus QUIC, illustrating how QUIC reduces round-trip times by combining the transport and cryptographic negotiations:

sequenceDiagram
    autonumber
    
    rect rgb(20, 20, 30)
        Note over Client, Server: TCP + TLS 1.3 Handshake (2 RTT)
        Client->>Server: SYN (TCP Handshake Start)
        Server-->>Client: SYN-ACK
        Client->>Server: ACK + TLS ClientHello
        Server-->>Client: TLS ServerHello + Finished
        Client->>Server: HTTP Request (Encrypted)
    end
    
    rect rgb(30, 20, 20)
        Note over Client, Server: QUIC Handshake (1 RTT)
        Client->>Server: QUIC Initial (ClientHello + Transport Parameters)
        Server-->>Client: QUIC Handshake (ServerHello + Handshake Finished)
        Client->>Server: HTTP/3 Request (Encrypted)
    end

Further Reading