TL;DR

  • Quad9 answers all six transports on one address, 149.112.112.112, so the transport is the only thing that changes. One client, q, on every arm.
  • One cold lookup, IP-layer bytes: Do53 168, DNSCrypt 1,052, DoT 7,186, DoH 7,781, DoQ 11,769, DoH3 12,420. Medians of 12 runs each.
  • DNSCrypt is the cheapest encrypted option here, by about a factor of seven against DoT. It has no TLS handshake to pay for.
  • The QUIC transports invert the direction. DoQ and DoH3 are the only arms where the client sends more than it receives, because RFC 9000 makes it pad every datagram carrying an Initial packet to at least 1,200 bytes.
  • Correction: the first version of this said DNSCrypt was the heavier one. It compared dnscrypt-proxy against q and blamed the protocols.

What the certificate costs

Everything built on TLS spends most of its cold budget receiving a certificate chain - roughly 5 kB of both the DoT and the DoH totals. DNSCrypt has none to fetch: one plain DNS query retrieves the resolver certificate, and the encrypted query follows, four packets in total. Plain Do53 is in the table as the floor rather than a recommendation, at two packets and 168 bytes with nothing encrypted and nothing authenticated.

The correction, and the rule it broke

An earlier version of this measurement, live for a few hours on the same day, reported the opposite: that a cold DNSCrypt lookup cost more bytes than a TLS 1.3 handshake, that the client sent 8,324 of them, and that every DNSCrypt query was padded to exactly 1,280 bytes. It also stated that no single client speaks both protocols, which was given as the reason for measuring at the wire in the first place.

That last claim was simply wrong - q speaks DNSCrypt given an sdns:// stamp - and it caused the rest. The measurement ran dnscrypt-proxy on one side and q on the other, then attributed the difference to the protocols. Measured with the same client on both sides, DNSCrypt sends 423 bytes where dnscrypt-proxy sends 8,324. The 1,280-byte padding and the oversized, fragmenting certificate probes are dnscrypt-proxy behaviour, not DNSCrypt behaviour. That is a real difference between two clients of one protocol, and worth knowing if you run dnscrypt-proxy, but it is not what was claimed.

The rule broken is one of our own: a test that varies one axis identifies the trigger, never the culprit. The client was the other axis and was never controlled.

The full table, the ranges, the correction in place, and a copy-paste script that measures all six against any resolver you choose: DNSCrypt vs DoH vs DoT vs DoQ.