Clever hacker fits 537,000 domains in a tiny $5 ESP32 ad-blocking dongle — firmware uses only around 50KB of RAM and can answer blocked lookups in 10 milliseconds
This project uses a clever hashing trick to fit over half a million blocked domains into just 4MB of flash memory.
How cheap can you build a hardware-based ad-blocking DNS filter? "Free," if you're willing to salvage some used hardware that's being thrown away. What if you aren't so lucky? In the era of the RAMageddon, even a Raspberry Pi will cost you a couple hundred bucks. But you know, you don't even need something that powerful. In fact, you can use a $5 microcontroller to build a fully functional ad-blocking filter with over 500,000 domains blocked and around 10ms latency.
We know that's possible because Egyptian full-stack developer ZedAxis (@M-Abozaid on GitHub) has already built one. Using an ESP32-C3 "SuperMini" board, he's created a backup DNS for his home network that still provides ad blocking. His primary router is a Pi-hole, which is a Raspberry Pi running specialized software to manage DHCP addressing and DNS resolution with integrated ad-blocking. The SuperMini serves as a backup when the Pi-Hole is rebooting or otherwise unavailable.
Strictly speaking, we haven't seen ZedAxis' creation in action, but there's no reason to believe it doesn't work. The ESP32 family of embedded Wi-Fi-enabled microcontrollers is a well-known quantity, and this functionality is by no means outside the realm of its capabilities. In fact, this specific trick allows the use of the ESP32-C3, which is a cost-reduced version of the chip that doesn't have the 8MB of PSRAM found on some higher-end models. (There are MANY variants of the ESP32.)
Instead, the ESP32-C3 used by ZedAxis has just 400KB of RAM, and 4MB of flash memory. With these limited specifications, he wasn't able to store a plaintext blocklist of any real size; it's simply too much data. So, he did what any enterprising hacker would do: he started hashing the data to reduce its size. Using 40-bit FNV-1a hashes, because 32-bit would give too many collisions and 64-bit wastes too much space, he can store some 537,000 domains in the flash memory of the device.
The clever part isn't really the hashing, though. Rather than storing the domains themselves, the build process downloads one or more public blocklists, strips out duplicate entries and comments, hashes each remaining domain into a 40-bit value, sorts the resulting list, and writes the finished database into the ESP32's flash memory. When a DNS query arrives, the device hashes the requested hostname the same way and performs a binary search against the sorted hash table. If it finds a match, the request is blocked. Otherwise, the query is forwarded to an upstream resolver. According to ZedAxis, the finished firmware uses only around 50KB of RAM while answering blocked lookups in roughly 10 milliseconds.
There's another neat compromise hiding in the design, too. The ESP32 normally reserves enough flash memory to hold two complete copies of its firmware, allowing over-the-air (OTA) updates without risking a failed flash leaving the device unbootable. If you don't care about wireless firmware updates, you can reclaim that second firmware partition for the blocklist database instead. With OTA support enabled, the project tops out at around 250,000 blocked domains. Give up OTA, and that jumps to roughly 537,000 domains on a microcontroller that you can usually buy for the price of a fast-food lunch. ZedAxis describes the price as $2; I wasn't able to find SuperMini boards any cheaper than about $5 US, but at that price there's not much need to quibble about the difference.
Of course, this isn't meant to replace a proper Pi-hole or AdGuard Home installation. The ESP32 project has a rudimentary dashboard, but it doesn't provide detailed per-client statistics, historical query logs, or all the knobs and dials that make those platforms attractive. Instead, it's designed as a tiny insurance policy. It sits quietly on the network, sips only a few dozen milliamps of power, and if the primary DNS server disappears for a reboot or a power outage, clients still get filtered DNS responses instead of falling back to whatever resolver the router happens to have configured.
Get Tom's Hardware's best news and in-depth reviews, straight to your inbox.
My favorite detail is that ZedAxis powers the whole thing from the USB port on the back of his ISP-provided fiber gateway, a Huawei OptiXstar home fiber gateway. The USB connection isn't carrying any data; the totality of the integration is the router saying "here's 5 volts" and the ESP32 replying "thanks." It's just that the port is a convenient power source for a device so small it practically disappears behind the router. All communications are carried out through the ESP32's integrated Wi-Fi adapter.
I have no idea whether projects like this will ever become common. Probably not, because most people who want network-wide ad blocking will still buy a Raspberry Pi, a used mini PC, or run AdGuard Home in a virtual machine. Still, it's refreshing to see somebody look at a $5 microcontroller with 400KB of RAM and decide, "Sure, that'll do."
Follow Tom's Hardware on Google News, or add us as a preferred source, to get our latest news, analysis, & reviews in your feeds.

Zak is a freelance contributor to Tom's Hardware with decades of PC benchmarking experience who has also written for HotHardware and The Tech Report. A modern-day Renaissance man, he may not be an expert on anything, but he knows just a little about nearly everything.
-
wakuwaku no matter how cheap a project is purported to be , as long as it requires you to either own a 3d printer, or get someone to print it for you, IT IS NOT CHEAP.Reply -
usertests Reply
An ever increasing number of people can get cheap access to a 3D printer through libraries (since nobody reads anymore) or makerspaces.wakuwaku said:no matter how cheap a project is purported to be , as long as it requires you to either own a 3d printer, or get someone to print it for you, IT IS NOT CHEAP. -
Unolocogringo Firefox + Ghostery +Malwarebytes Browser guard, makes it simple. No hardware needed.Reply
Spybot Anti Beacon takes care of windows telemetry.
Simple and effective. -
USAFRet Reply
I print LOTS of things for friends and coworkers for $0.wakuwaku said:no matter how cheap a project is purported to be , as long as it requires you to either own a 3d printer, or get someone to print it for you, IT IS NOT CHEAP. -
krisavi Replywakuwaku said:no matter how cheap a project is purported to be , as long as it requires you to either own a 3d printer, or get someone to print it for you, IT IS NOT CHEAP.
There is no NEED for 3d printer. You can print an enclosure, but you don't have to do it. -
krisavi Reply
That is so one OS specific answer to some neat thing someone uses.Unolocogringo said:Firefox + Ghostery +Malwarebytes Browser guard, makes it simple. No hardware needed.
Spybot Anti Beacon takes care of windows telemetry.
Simple and effective.
A lot of people use PiHole to block ads/domains on phones. You being able to do something on windows would not do much on phones.
This project is nice addition to keeping that blocking working while main system is updating. -
darkflib If you are hashing and binary searching, a bloom filter might be a better choice if tuned well.Reply -
Unolocogringo Reply
I use the same combo on my android phone, except anti beacon, which is windows specific.krisavi said:That is so one OS specific answer to some neat thing someone uses.
A lot of people use PiHole to block ads/domains on phones. You being able to do something on windows would not do much on phones.
This project is nice addition to keeping that blocking working while main system is updating.
Works wonders.
Kudos to the maker. It fits his specific need.
To the other 90++% of us my combo is simple and effective.
For windows, those with the knowledge, would edit the hosts file to achieve the same purpose.
And I believe Linux has a similar solution. With my limited use of it for folding. -
evermorex76 If there was a power outage why would you keep your wireless network up, plus whatever wired connectivity it uses, plus your Internet service provider's device(s) (my AT&T fiber uses a separate converter rather than an integrated fiber port on the gateway), plus whatever non-wireless devices you might need to stay online, but not keep your PiHole powered, unless you're running it on something ridiculously overpowered? On a Raspberry Pi 4, 15W max and probably a lot less as a PiHole wouldn't exactly drain a UPS like a camel at a trough. You are running right on the edge of capacity if that's the straw that breaks the camel's back for runtime. A Raspberry Pi also doesn't take THAT long to boot, and can be done at a convenient time, although I get that there might be some situations where lookups can't take that long (I think your web browsing, which is where the blocking is needed, would tolerate it). Not saying this device is useless or not a neat piece of work, though, just of very limited utility in most situations, and those situations could be very easily mitigated so it wouldn't be needed. Extended power outage, working solely on a mobile device on Wi-Fi and trying not to use mobile data, stretching out UPS runtime as long as possible with just the ISP gateway connected.Reply
537k domains in 4MB didn't seem like much, but then I realized compressing that data wouldn't be possible with the processing power and limited RAM resulting in the need to read the data directly from the flash each time, which wouldn't allow looking at individual lines from a compressed file. I looked up how hashing reduces the size of the text and just got confused. I get the basic idea but not the exact details. I just have never been able to get my head around concepts like bitwise XOR.
The math gives me about 2.56MB of space needed for the data to be stored with 537k domains, and about 48% of that with the second copy of the firmware still there. But you make it sound like he couldn't fit any more domains in the list, and 537k was only after deleting the second firmware copy. Does this device really use roughly 1.4MB of its storage space just for each copy of the firmware out of the box? That doesn't leave much for the user to actually do anything with it. I guess it's a very limited device so the limited amount of work it can do means not needing much stuff to be stored, and projects needing more storage would probably need a more powerful device anyway. I'm surprised 4MB chips are even produced anymore, or such tiny RAM chips.
If 256k was the original number, but he was able to expand that to 537k, the wording in the article implies there were even more domains but there wasn't space. How is the software choosing which domains to include in the list if the collection of blocklists includes more unique domains than the storage can hold? Does it just drop blocklists one by one until the list is small enough (maybe looking at the number in each blocklist and figuring out a combination of them that would remove the right number, rather than a fixed order that might drop too many unnecessarily)? Then if one of the blocklists grows, it could cause the list to get too big and the device would need to drop even more blocklists. It would constantly become less and less effective at its job as there were more and more domains that it wasn't blocking, but also increasing the size of the list would provide more chances for collisions in the hashes. Was 40 bits chosen specifically as a match to the possible number of domains that could be stored, so doing this with more storage space and more domains would almost immediately require larger hashes to allow for an acceptably low chance of collision?
I've considered network level blocking devices a few times, but not being able to manage a single device's access quickly makes it no good for me. With browser extensions, it's just a couple of clicks to temporarily or permanently unblock a site to allow scripts or ads if I need it to work for one piece, but not clutter a permanent allow list, or use a different browser that doesn't have blocking enabled. I use AdGuard's free service on my phone, and it's annoying to not be able to read some sites because an ad domain is blocked so the page blocks the content, and I can't choose to allow it.