HTTP/3 and QUIC support in Caddy is enabled by default on all recent versions.
Let’s see Caddy in action. Imagine you have a simple website served by Caddy, and you want to ensure it’s using the latest and greatest protocols for faster, more reliable connections.
Here’s a typical Caddyfile for a basic static site:
example.com {
root * /var/www/html
file_server
}
When Caddy starts with this configuration, it automatically negotiates HTTP/3 with compatible clients. You don’t need to explicitly tell it to "enable" HTTP/3 or QUIC. Caddy’s philosophy is to provide modern, secure defaults. If a client supports HTTP/3 and QUIC, and the network conditions are favorable, Caddy will use it.
To verify this, you can use your browser’s developer tools. Load https://example.com (assuming you’ve configured DNS and have Caddy running). Open the Network tab in your browser’s developer tools, refresh the page, and inspect the "Protocol" column for the main document request. You should see h3 (for HTTP/3) or h3-29 (an older draft, but still indicative).
Internally, Caddy uses the quic-go library to handle QUIC and HTTP/3. This means Caddy is essentially speaking UDP (for QUIC) and managing the connection state, encryption (TLS 1.3 is mandatory for QUIC), and HTTP/3 framing itself. When a client connects, Caddy advertises its support for HTTP/3 via the Alt-Svc (Alternative Service) header. This header tells the client, "Hey, you can also reach me on this other address and protocol."
For example, a successful Alt-Svc header might look something like this:
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
This tells the browser that it can connect to example.com on UDP port 443 using HTTP/3. The ma parameter is the max-age in seconds, indicating how long the browser should remember this alternative service.
The primary levers you control with Caddy are related to TLS, as QUIC relies heavily on TLS 1.3. Caddy manages TLS certificates automatically using Let’s Encrypt. If you have custom certificate requirements, you can specify them in the Caddyfile:
example.com {
tls mycert.pem mykey.pem
root * /var/www/html
file_server
}
However, even with custom certificates, Caddy will still attempt to use HTTP/3 by default. The protocol negotiation is independent of the certificate management, as long as the certificate is valid.
The beauty of Caddy’s approach is that it abstracts away the complexity of setting up HTTP/3. You don’t need to configure separate listeners, manage QUIC-specific parameters, or manually enable specific modules. Caddy’s core server handles the protocol negotiation and transport. This allows developers and operators to focus on their application logic rather than the intricacies of network protocols.
One thing many people don’t realize is how Caddy handles fallback. If a client tries to connect via HTTP/3 but encounters network issues (like a firewall blocking UDP traffic on port 443, or a router that doesn’t properly handle QUIC), Caddy will gracefully fall back to HTTP/1.1 or HTTP/2 over TCP. This is managed through the Alt-Svc header and the client’s own connection logic. Caddy doesn’t "force" HTTP/3; it offers it as a superior option when available and usable. This ensures maximum compatibility and resilience for your users.
The next step in optimizing web performance with Caddy would be to explore its advanced load balancing and reverse proxy features.