Codex helped me start a hardware project: an ESP32 Ad Blocker

October 7, 2026 • Mastodon • RSS

Before, I used Codex only on digital products, but then I realized that it could also be used to get started with hardware more easily than ever before. Without learning a new programming language, I could ask Codex to help me change the firmware of a microcontroller.

So I bought an ESP32 and asked it to help me build an ad blocker for my local network.

Ad blocking on an ESP32

ESP32 DNS filter

I found M-Abozaid’s ESP32-C3 AdBlock project on GitHub and adapted it to my ESP32-D0WD-V3 board. I’ve been fascinated by two ideas:

The trick everyone misses: you do not need to keep the blocklist in RAM. Store the domains as sorted 40-bit hashes in flash and binary-search them. 140,000+ domains fit in ~0.7 MB of flash and are matched in ~10 ms, using ~50 KB of RAM.

This means that a simple device can handle a job traditionally done by a Raspberry Pi or a dedicated server.

Another idea that I found absolutely genius is that you can attach the ad blocker to the router by USB—not to connect the firmware to the router, but simply to power the ESP32, as shown in a post by Psalteric.

USB power connection on the router

On top of that, I used an e-ink display to show some basic information, but that part was purely optional.

ESP32 Ad Blocker running beside the router

Note: the 8% shown on the display is the share of DNS requests blocked in that snapshot, not an 8% measure of the ad blocker’s effectiveness. It depends on the traffic, websites, devices, and time period being observed.

So now my ESP32 ad blocker contains a blocklist combining StevenBlack Base and HaGeZi Light, with 100,331 sorted 40-bit hashes. Blocked A records return 0.0.0.0, while blocked AAAA records return an empty answer. The ESP32 handles DNS only; web traffic still goes directly from each client to the internet.

Improving the ESP32 Ad Blocker

The firmware uses asynchronous UDP ingress, response and decision caches, a prefix index, and six-millisecond reply pacing. AI agents helped me inspect the code, adapt the display task, test the DNS behavior, and verify the firmware image against the physical flash limits.

The DNS implementation was also significantly improved:

Improving website loading time on macOS

Switching between macOS and FreeBSD, I noticed how fast networking feels on FreeBSD and how noticeably slower it can be on macOS. So I started investigating this with Codex.

After some tests, it found better TCP settings for macOS, which improved website loading.

For these tests, I tuned several macOS TCP parameters, including the default MSS, send and receive buffer sizes, TCP window scaling, and delayed ACK behavior.

Then I combined those changes with the ESP32 AdBlocker to speed things up even more.

Ethernet results

ConfigurationMedian navigation time
ESP32 DNS / Optimized TCP0.364 s
Router DNS / Optimized TCP0.423 s
Router DNS / Default TCP0.447 s

Wi-Fi results

ConfigurationMedian navigation time
ESP32 DNS / Optimized TCP0.378 s
Router DNS / Default TCP0.432 s
Router DNS / Optimized TCP0.433 s

With these changes, websites load blazing fast. Sometimes it feels almost as if they were opened from local storage rather than from the web.