There are hundreds of millions of unexpired certificates on the public web, and some fraction of them have been revoked — keys leaked, domains changed hands, CAs caught a mis-issuance. The list of revoked ones is the answer to a question your browser is supposed to ask on every HTTPS connection: is this certificate still good?
For twenty years that question was answered badly. The full revocation list was too big to ship, so browsers asked the CA one certificate at a time over OCSP — which leaked your browsing to a third party and, worse, failed silently open the moment an attacker blocked the lookup. In August 2025 Let’s Encrypt turned its OCSP responders off entirely, and almost nothing broke, because the check had been theater for years.
So here’s the surprising part. As of Firefox 137, shipped April 1, 2025 and enabled for every desktop user by default, the browser does the thing everyone said was impossible: it downloads the entire web’s revocation list and checks certificates against it locally, with no network round-trip, revealing nothing to anyone. The whole list of every revocation on the WebPKI fits in a few megabytes. This is CRLite, and the reason it works is a genuinely clever piece of engineering that turns a data structure famous for being approximately right into one that is exactly right.
Why “just download the list” was always the obvious answer, and always failed
The original revocation mechanism, the Certificate Revocation List, was exactly this: the CA publishes a signed file of every serial number it revoked, and clients download it. It’s the honest design. It fails on size — CRLs grew large and stale, clients didn’t want to pull megabytes of serial numbers per CA before every connection, and so the industry drifted to OCSP’s one-question-at-a-time model instead. That traded a size problem for a privacy problem and a fail-open problem, both of which turned out to be worse.
CRLite goes back to the original idea — ship the whole list — and beats the size problem hard enough that it stops being a problem. The naive full list is hundreds of megabytes. Mozilla’s 2020 writeup put roughly 300 MB of revocation data into about 1 MB. Today a Firefox client pulls an average of ~300 kB of revocation data per day: a fresh snapshot of a few megabytes every 45 days, with small delta updates in between, and the local filter refreshes every 12 hours. The entire revocation state of the public web, kept current, for less bandwidth than a single web page.
How do you get there? Not with ordinary compression. You get there by realizing you don’t need to store the certificates at all — you only need to answer one bit per certificate: revoked, or not.
The Bloom filter, and the problem with it
A Bloom filter is the classic data structure for “is this thing in the set?” using almost no space. You hash the item, flip a few bits in a bit array, and to test membership you check whether those bits are set. It’s tiny and fast. The catch, the thing every textbook warns you about, is that it can produce false positives: it will occasionally say “yes, in the set” about something that isn’t. It never produces false negatives — if it says “not in the set,” that’s certain — but the false-positive rate is the price of the compression.
For revocation, a false positive is a disaster. If the filter wrongly says a valid certificate is revoked, the browser refuses to load a perfectly good site, and the user gets a security error on a bank that did nothing wrong. A revocation system that occasionally breaks good sites at random is worse than no system. So a plain Bloom filter, for all its elegance, looks like exactly the wrong tool: it’s approximate, and revocation demands certainty.
Here is the move that makes it work.
The closed-world trick: a cascade that cancels its own errors
CRLite has an advantage that most Bloom-filter applications don’t: it knows the entire universe of certificates. Certificate Transparency — the public, append-only logs that every publicly-trusted certificate must be submitted to — means Mozilla can enumerate essentially every valid certificate on the web, not just the revoked ones. It knows both sets: everything that exists, and everything that’s revoked.
When you know both sets in advance, you can build the filter and then audit it against reality before shipping it.
- Build a Bloom filter over all the revoked certificates. It answers “revoked” for every truly revoked cert (no false negatives), plus some false positives — a handful of valid certs it wrongly flags.
- Because you have the full list of valid certificates, you can find exactly which valid certs got false-positived. Build a second filter over just those — a filter whose members are “valid certs the first filter got wrong.”
- That second filter has its own false positives, drawn from the revoked set this time. So build a third filter over those. And so on.
Each layer catches the mistakes of the layer above it, over an ever-smaller set, so the layers shrink fast — usually the cascade is only a handful deep. To check a certificate at runtime, you walk down the layers: the last layer that claims membership decides the answer. Because the cascade was built against the complete, known universe, it produces zero false positives and zero false negatives over every certificate that existed when it was built. The probabilistic structure gives an exact answer, because the problem is closed-world. You can only pull this off when you already hold the whole map — which Certificate Transparency, a system built to audit CAs, quietly made possible as a side effect.
That’s the part worth sitting with. CT was designed so that mis-issued certificates couldn’t hide. A decade later, the same public ledger is what lets a browser carry every revocation in its pocket. Infrastructure you build for one guarantee becomes the substrate for another you didn’t plan.
What shipped is already past the paper
The 2017 academic design — CRLite: A Scalable System for Pushing All TLS Revocations to All Browsers, by researchers at Northeastern, the University of Maryland and Duke — used the multi-level Bloom cascade above. What Firefox actually ships in 2025 has already moved on. Mozilla built a set-membership scheme it calls Clubcard that replaces the multi-level Bloom cascade with a partitioned two-level cascade of Ribbon filters — Ribbon filters being a newer, more space-efficient cousin of the Bloom filter. The reason for the change was mundane and telling: bandwidth. The delta updates in the original design were bigger than they wanted to push to every user every few hours, so they re-engineered the encoding to shrink them. The core idea — a cascade that cancels its own false positives against a known universe — survived; the filter primitive underneath got swapped for a better one.
Why this is still the exception, not the norm
CRLite is, as of now, a Firefox thing. Chrome went a different direction over a decade ago: it stopped doing live revocation checks and pushes CRLSet, a curated list of high-value revocations that Google compiles and decides is worth including. CRLSet is deliberately not comprehensive — it’s a shortlist, not the whole map. So the two browsers that dominate the web have opposite philosophies: Chrome ships the revocations it judges important; Firefox now ships all of them.
And the industry’s third answer, the one that quietly won, was to make the question matter less. Certificate lifetimes are collapsing — from years, to 398 days, to 200 now, to 47 by 2029. A certificate that’s only valid for a few weeks limits the damage of a leaked key to a few weeks whether or not anyone checks revocation. That’s the pragmatic bet: don’t fix “undo,” just shrink the window it applies to until failing at it stops hurting.
CRLite is the more ambitious answer — actually making the closed-world guarantee that revocation always promised and never delivered. It has real dependencies: CAs have to keep publishing usable CRLs, CT has to stay complete, and someone has to run the aggregation pipeline. But for the first time, the honest design — download the list, check it locally, tell no one — is the one that fits. The list was never really too big. We just didn’t know how to fold it.