Open-Source Wikis

/

Envoy

/

Features

/

QUIC and HTTP/3

envoyproxy/envoy

QUIC and HTTP/3

QUIC is a UDP-based transport that combines TLS 1.3 with stream multiplexing, low-latency handshake, and connection migration. HTTP/3 is HTTP over QUIC. Envoy delegates the protocol implementation to Google's QUICHE library and wires it through Envoy's listener/dispatcher/codec abstractions in source/common/quic/.

What QUIC means for Envoy

  • UDP, not TCP — listeners and connection pools are UDP variants.
  • Crypto in the protocol — there is no "TLS layer" beneath QUIC; the stack itself terminates TLS 1.3.
  • Streams — like HTTP/2 but at the transport layer, with no head-of-line blocking across streams.
  • Connection migration — clients can move between IPs without resetting the connection.
  • 0-RTT — once a session is cached, the next request can ride on the first packet.

Where the code lives

Concern Path
Server-side listener active_quic_listener.cc, envoy_quic_dispatcher.cc
Server session/stream envoy_quic_server_session.cc, envoy_quic_server_stream.cc
Client connection / pool envoy_quic_client_connection.cc, envoy_quic_client_session.cc, source/common/http/http3/conn_pool.cc
HCM codec server_codec_impl.cc, client_codec_impl.cc
Transport-socket bridges quic_server_transport_socket_factory.cc, quic_client_transport_socket_factory.cc
Crypto bridges envoy_quic_proof_source.cc, envoy_quic_proof_verifier.cc
GSO / IO udp_gso_batch_writer.cc
QUIC extension factories source/extensions/quic/ — proof source, connection ID generator, server preferred address, crypto stream.

The QUICHE source is vendored under bazel/external/quiche.BUILD.

Server-side flow

sequenceDiagram
    participant Listener as ActiveQuicListener
    participant Disp as EnvoyQuicDispatcher
    participant Sess as EnvoyQuicServerSession
    participant FilterMgr as Network filter chain<br/>(starts with HCM)
    participant HCM as ConnectionManagerImpl
    participant Stream as EnvoyQuicServerStream

    Listener->>Disp: incoming UDP datagram
    Disp->>Sess: route to existing or new session
    alt new session
      Sess->>Sess: TLS 1.3 handshake
      Sess->>FilterMgr: instantiate filter chain (incl. HCM)
    end
    Sess->>Stream: new HTTP/3 stream
    Stream->>HCM: codec emits headers/body to HCM
    HCM->>Stream: encodes response

The QUIC listener uses a UDP ActiveListenerBase (under source/common/listener_manager/) and dispatches incoming datagrams to QUICHE's QuicDispatcher via the Envoy bridge in EnvoyQuicDispatcher.

Client-side flow

The client side is reached through Http::ConnectionPool::Instance for HTTP/3, configured via cluster transport socket. HttpConnPoolGrid (see connection pools) decides whether to try HTTP/3 first.

Crypto

QUIC requires its own TLS handshake in-protocol. Envoy bridges to BoringSSL via:

  • EnvoyQuicProofSource — server-side cert chain provider.
  • EnvoyQuicProofVerifier — client-side cert verifier.

These are wired with the same Ssl::ContextConfig plumbing as the TLS transport socket, so SDS-driven cert rotation works for QUIC.

Stat scopes

QUIC emits its own stats under listener.<addr>.http3.* and cluster.<name>.http3.*. The stat names are pre-allocated in quic_stat_names.h for hot-path efficiency.

GSO

On Linux, the UDP send path uses Generic Segmentation Offload (GSO) — multiple QUIC packets in one sendmmsg. udp_gso_batch_writer.cc implements the writer. This is a major throughput win on busy edges.

Connection ID generators

QUIC connections survive client IP changes because they are keyed by a connection ID, not the 4-tuple. The way the server allocates IDs is pluggable so deployments can encode routing information into them (e.g. AWS NLB-friendly IDs, deterministic IDs for sharding). See envoy_deterministic_connection_id_generator.cc and the factory interface in envoy_quic_connection_id_generator_factory.h.

HTTP/3 codec

Server and client codecs (server_codec_impl.cc, client_codec_impl.cc) implement Http::ServerConnection / Http::ClientConnection so the HCM and router can talk to QUIC streams without knowing they aren't HTTP/2.

CONNECT-UDP and HTTP datagrams

Envoy supports CONNECT-UDP tunnelling and HTTP datagrams (http_datagram_handler.cc) for proxying QUIC over QUIC and for WebTransport-style datagrams.

Mobile relevance

Envoy Mobile ships the QUIC client stack for iOS / Android. The connection migration semantics matter especially on mobile where networks change frequently.

Configuration

Enable HTTP/3 on a listener:

listeners:
- name: h3_listener
  address:
    socket_address: { protocol: UDP, address: 0.0.0.0, port_value: 443 }
  udp_listener_config:
    quic_options: {}
    downstream_socket_config:
      prefer_gro: true
  filter_chains:
  - transport_socket:
      name: envoy.transport_sockets.quic
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.quic.v3.QuicDownstreamTransport
        downstream_tls_context: { common_tls_context: { ... } }
    filters:
    - name: envoy.filters.network.http_connection_manager
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
        codec_type: HTTP3
        http3_protocol_options: {}
        ...

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

QUIC and HTTP/3 – Envoy wiki | Factory