Ivan Bohun · a self-hosted swarm
It is being served to you, right now, by four ESP32-S3 microcontroller blades, sitting on a shelf in a London flat. They are watched over by two more observer units that witness and visualize the swarm.
The router forwards every request to one immortal virtual MAC address: the mask, worn by whichever blade won the election. The wearer hands your connection to the least busy blade, so you are answered by a different microcontroller from the one you connected to.
Every blade carries both programs, balancer and server, and the mask moves between them by election, held over encrypted radio, off the wire.
The page you are reading lives in flash memory, brotli-compressed, behind a TLS 1.3 handshake that terminates on a 240 MHz microcontroller.
No AWS. No landlord. No rent.
Live
This table is not a screenshot. Your browser is polling /roster on the same
machine that sent you this page, every three seconds. The blades gossip over an encrypted
ESP-NOW radio mesh once a second, and each heartbeat carries the fleet's whole picture: who
is alive and serving, how strong every link is, what each blade has answered and how fast,
and what the balancer has relayed.
| Node | Role | Status | Link | Served | Temp | Uptime |
|---|---|---|---|---|---|---|
| reading the roster… | ||||||
The names come from the Cossacks: the otaman is the
elected leader, wears the mask and hands every arriving connection to somebody else,
while each kozak does the actual work of answering it. Every serving blade
carries both programs, so which one it is doing depends only on who currently holds
the address. The pysar is the scribe that watches and keeps
the record, and the kobzar is named for the wandering bards who carried Cossack
history in song - here, the big screen that keeps the swarm's chronicle.
Since the fleet
started balancing, the elected node stops serving pages itself: it holds the mask,
takes every incoming connection, and splices it to a kozak that does the TLS work.
It works at layer 4, TCP, and never sees where one request ends and the next
begins, so it counts connections while the blades count requests -
those are different numbers, since your browser pulls this page, its
favicon, the og image and every roster poll down a single connection it keeps open.
The blades' figures in the table are requests; the otaman's is their sum.
Connections received is what arrived at the door since this node was elected,
relayed is what reached a clean finish, and connections refused is what
was turned away instantly because every backend was already busy.
Broken mid-transfer is a connection that died in flight, usually a reader
closing the tab; closed after stalling is one that went silent and was cleaned
up rather than left squatting a slot. In the second row, connect to backend is
how long the balancer waits to reach a kozak, and time to TLS first byte is how
long until that kozak sends its first TLS byte back. The response times come from
the blades instead - each kozak times every request it answers and reports its own
p50 and p95, and these are the average across the serving ones.
Ivan Bohun broke his sabre rather than swear the oath,
and legend says the shards return when the land is free.
Cossack colonel · kharakternyk
Architecture
The trick that makes a swarm of disposable microcontrollers behave like one durable server is that the identity is not attached to any of them. The blade holding the identity acts as a Level 4 TCP splicer, relaying your connection to one of the downstream serving blades. The fleet behaves like a single machine, but the work is spread across all of them.
The machine itself. Four serving blades on their pads, each with its own jack into the six-port fabric. The small screen is the pysar keeping the roster; the 4.3 inch touch panel is the kobzar keeping the chronicle. Along the front edge runs an SK6812 rail with one pixel per member: lime for the otaman, white for the kozaky, blue for the pysar, purple for mission control. Your request enters at the switch, rides the lime cable up to the mask holder, and is spliced back down the green one to the kozak that answers it.
The mask. The address you connect to is a locally administered MAC that no factory ever issued. The elected leader writes it into its own Ethernet controller and claims the static IP. Lose that node and the next one in line writes the same address into itself, sends a gratuitous ARP so the switch relearns the port, and carries on answering. The visitor never learns that anything died.
One request, end to end. The otaman splices the raw bytes to the least busy kozak, so the encrypted session runs from your browser straight past the balancer. The backend set comes from the radio - every blade broadcasts its state once a second.
The ladder down. A blade is declared lost 3 seconds after its last heartbeat; the next in line wins the election, takes the mask and rebuilds its backend set from the gossip roster. A leader that stands down deliberately closes its relays first; one that dies takes its relays with it. The last blade standing splices to its own server over loopback.
Resilience
Each blade watches its own health, probing its own public port every 7 seconds. The blade that balances watches twice: itself the same way, and the whole fleet through every relay it opens. Either signal can pull a blade out of rotation.
Two health checks. Each blade opens a TCP connection to its own public port every 7 seconds: two failures and it stands down, six and it crashes on purpose so the coredump shows where its server was stuck. The balancer separately benches any backend that accepts connections and returns nothing three times running - 15 seconds, doubling to a 4 minute cap. One byte back clears it.
On the glass
Two touchscreens and a strip of light, all fed by the same 1 Hz heartbeat the blades already send each other. No polling, no server, no dashboard in a browser somewhere - the instruments are part of the machine.
Identity, the vMAC, every member with signal strength, delivery ratio and uptime, then quorum, request count, latency and average RSSI. The six chips along the bottom mirror the physical rail, pixel for pixel.
Green follows the mask wherever the election moves it. Pull a blade’s power and its pixel turns red inside three seconds; push a release and it holds amber for the length of the transfer.
Boot walks four dots - white, green, blue, red - proving every joint is functional before the roster paints.
A wider glass for wider truth: health badge, live release progress, sixty-sample sparklines per node and a scrolling chronicle of everything the swarm has done.
It also renders this very page, baked to a pixel strip and scrolled by finger.
Made by hand
None of this arrived assembled (unintentionally). Every header, every breakout, every wire in the level shifter was soldered on a kitchen table by someone who had barely held a soldering iron in July 2026, and every joint was proven with a multimeter before it was ever given power.
Fifteen-pin strips down both flanks of every blade, soldered from the jack side so the pins rise where the Duponts land. Continuity beeped pin by pin, and a diode-drop baseline taken on all nine boards - 0.486 to 0.503 V, tight enough to prove no cold joints.
Four USB-C breakouts pinned by hand, and every one of them carries all four wires now: power, ground, and both data lines into the ESP32-S3’s native USB. The data pairs were an afterthought that became doctrine the night a bad update bricked the fleet’s own update door - since then each blade flashes from its own port, no dongle, no harness-swapping, and one board’s reversed pin order is why every pair met a multimeter before it met a computer.
A rainbow of female-to-female Duponts carries SPI, backlight and touch from the DevKitC to the 2.8″ glass. Nothing on a display is permanent: every link pulls apart, so replacing a dead panel needs no soldering iron.
The blades speak 3.3 volts; the LEDs listen for five. A 74AHCT125 quad buffer on a solderable breadboard translates - fourteen chip legs, eleven jumpers routed hole by hole, a 330 Ω resistor to soften the edge, and six header pins so every wire beyond it stays push-fit.
Thirty measurements before the first electron: no rail shorted to another, eleven grounds beeping to one net, five volts where five volts belonged, and 325.6 Ω on the signal path. The board was correct by instrument before it was ever plugged in.
The display board’s 5 V pin turned out to be isolated by design - a clone quirk that starved the rail at 2.6 volts and kept it dark. Two blobs of solder across the manufacturer’s own jumper pads joined it to USB power, and the rail lit on the first try afterwards.
Next, the naked boards get walls: each blade moves into its own 3D-printed kurin - a ventilated barracks it slides into like a drawer, RJ45 nose out, a wire bay for the breakout and the slack. Case by printed case, the swarm becomes a frankenstein imitation of manufacturing.
A ten-inch rack drawn to our own spec: kurins side by side on one shelf, jacks aft toward the switch, both screens facing forward through a CNC-cut smoked-acrylic face.
Principles
Only the node wearing the mask answers the world. The other blades receive their visitors through it over the LAN and send nothing outward on their own, so from outside the swarm looks like a single quiet machine.
Nothing shuts down gracefully because nothing needs to. There is no state worth preserving on any node. Pulling the plug is a supported operation and the only recovery procedure is to boot.
The address is a locally administered MAC chosen by hand and passed between blades by election. No provider issued it and none can revoke it.
The entire site is a single brotli-compressed HTML file with no external fonts, scripts, trackers or CDNs. A first-time visitor pays for one TLS handshake and one response.
The lowest numbered candidate that is healthy both on radio and network leads. Every node computes the same answer from the same heartbeats, making leader election deterministic.
Every blade boots into its own identity before it is eligible to lead, so a bad release can always be replaced remotely. The swarm can be rebuilt over the air without anyone touching a cable.
Every blade routinely opens a TCP connection to probe its own public port. Two failures and it stands down from the election; six and it reboots. A blade that cannot reach itself has no business receiving visitors.
The balancer ignores what a blade claims about itself. A backend that goes silent on three relays in a row is benched for 15 seconds, and each repeat doubles the bench, up to four minutes.
Lose the leader and the next blade becomes one in seconds. Keep losing blades and the backend set shrinks with the fleet, down to the last survivor splicing to its own server over loopback.
Who built it
Principal Engineer in London, fifteen years in distributed systems, performance engineering and the kind of reliability work that “only goes in one direction” ↑. The swarm above is the sort of thing I do for fun. Below is what I have done at work.
Tenth engineer in. Shaped hiring and grew the team past seventy. Built the Community Integrity vertical from the ground up. Led the first Platform Engineering group to rebuild the mission-critical Coin infrastructure carrying most of the traffic.
Led Trust engineering against fraud and abuse at scale, led the company-wide compute efficiency programme, architected and delivered the real-time ML feature platform behind novel Fraud Detection models into production.
Sole Principal across an eighty-person engineering org. Took the Royalty Processing Engine from on-premise Oracle PL/SQL to a fully streamed AWS pipeline, designed, built and delivered the Chain of Title system that the business runs on. Primary technical IC for due diligence through the sale to Francisco Partners.
Performance and reliability for video delivery across forty thousand device types. Profile-guided and post-link binary optimisation of the rendering framework on living room hardware, which is where the taste for squeezing constrained devices came from.
Led European Expansion across product, engineering, operations and support, a group of more than a hundred people, and re-architected core payment processing along the way.
HappyCar staff engineer on early AWS microservices (2014-2015) · ironSource high-load realtime billing pipelines, among the first AWS Redshift adopters worldwide (2013-2014) · Sixt / DriveNow backends behind the car-sharing launch across European capitals · Softheme engineering lead.
Kyiv Polytechnic Institute, MSc and BSc in Computer Science, summa cum laude. Computer Systems and Networks, with post-graduate research in cryptanalysis on resilient S-Box construction meeting the Strict Avalanche Criterion.
Python - mother tongue · Java - father tongue · Go (it grows on you) ·
TypeScript (regretfully) · Lua (when possible) · C++ · Rust (when going deep) ·
terrible C on bare metal (when the occasion calls for it) ·
ASM (for occasions that never call)
Stateful stream processing, distributed tracing, fleet-wide continuous profiling,
performance engineering from datacentre scale all the way down to a microcontroller
with 8 MB of RAM.
Donate to Ukraine’s defenders
or place your trust
in me directly by donating in support of the Ukrainian Medical Corps with best-in-class
hemostatic agents, procured at manufacturing source and shipped straight to the front line
hotspots where the need is most critical.
$50 saves a life - literally.
$150,000+ deployed, 2250+ Celox Haemostatics delivered so far.
Full nomenclature is and always will be publicly available here