← projects

pq-census

Measuring how much of the web uses post-quantum TLS

GoTLSCryptography

Encrypted traffic can be recorded today and decrypted years from now, once quantum computers are strong enough: “harvest now, decrypt later.” The defense already exists. A hybrid key exchange, X25519MLKEM768, pairs classic X25519 with ML-KEM, the post-quantum algorithm NIST standardized in 2024 (FIPS 203). Chrome and Firefox offer it on every connection. Whether you actually get it depends on the server.

So I measured it. pq-census connects to the 10,000 most popular sites on the Tranco list and records the key exchange each one picks, along with the TLS version and who serves the site.

10,000

sites scanned

7,340

answered over HTTPS

55.7%

of those post-quantum

15.5%

still on TLS 1.2

Your CDN Decides

Post-quantum share by who terminates TLS

Amazon CloudFront
698 sites
99.6%
Cloudflare
1,948 sites
97%
Vercel
74 sites
96%
Akamai
272 sites
85%
Fastly
272 sites
81%
Microsoft Azure
47 sites
68%
Google
362 sites
58%
Self-hosted / other
3,283 sites
20%
Netlify
30 sites
7%
AWS ELB / S3
272 sites
4%
Share of each provider’s reachable sites that negotiated X25519MLKEM768. The provider is whoever terminated TLS, detected from response headers. Scanned September 30, 2026.

What the Data Shows

  • —Popularity barely matters: 53.4% of the top 100, 55.2% of the top 1,000 and 55.7% of the top 10,000. What matters is the provider in front of the site
  • —The big CDNs turned it on for everyone: 97% behind Cloudflare and 99.6% behind CloudFront. Self-hosted sites are at 20%
  • —The same company can be on both sides: Amazon's CDN is nearly all post-quantum, while sites on its load balancers and S3 are at 4%
  • —Only one post-quantum method is in use: all 4,086 post-quantum sites chose X25519MLKEM768
  • —1,135 sites (15.5%) still run TLS 1.2, which can't negotiate a post-quantum key exchange at all
$ go run . scan -list top-1m.csv -n 10000 -out results.jsonl -q
10000 domains, 0 already scanned, 10000 to go
done: 10000 scanned this run, 4086 post-quantum, 5m22s

$ go run . report -in results.jsonl
Scanned 10,000 sites. 7,340 answered over HTTPS;
4,086 of those (55.7%) negotiated a post-quantum key exchange.

How It Works

  • —Go's default TLS client offers X25519MLKEM768 first and plain X25519 alongside it, like current browsers, so the group that gets negotiated is the server's choice
  • —One HEAD request per site, with redirects not followed: the measurement is the handshake with the domain itself. If the bare domain doesn't answer, it tries www
  • —The handshake is captured with httptrace as soon as it completes, so a site whose TLS works but whose HTTP layer then fails still counts
  • —Every failure is classified (DNS, timeout, connection reset, TLS error), and domains that resolve to private or loopback addresses are skipped
  • —Scans resume after an interruption, and the raw results, report and Tranco list ID are published so anyone can rerun it

Surprises along the way

My own network was hiding sites

About 6% of domains reset the connection mid-handshake, identically with post-quantum and classical handshakes. That pointed at a filter, not the sites. A second machine on the same network saw the same resets, so I counted them as unreachable rather than guess, and documented it as a limit of the measurement.

Windows Defender called my scanner a trojan

Running it from my desktop, Defender's machine-learning detection quarantined the binary (Bearfoos.A!ml) about 30 seconds in: a new, unsigned program opening hundreds of connections a minute looks like malware. A false positive, but a real-world lesson about what network measurement tools look like to endpoint security.

A bug in my own measurement

The first version only recorded a site if its HTTP request succeeded, so a site that negotiated post-quantum TLS but then returned an HTTP/2 error was thrown away. Capturing the handshake on its own fixed it, and a test now covers that case.

Limits

  • —One vantage point (a US residential connection) at one moment. Large sites can answer differently by region or load balancer
  • —It measures what servers support, not what share of real traffic is post-quantum
  • —Provider detection relies on response headers, so sites that strip them are counted as self-hosted