Tools
A feature smith works with tools. These are mine: what I used each one for, the odd things I did with it, and where.
AI and LLMs
- LLM agents2018–now
Agents as workers: persistent sessions, a web interface, durable jobs, and an AI engineering framework a product team used every day.
- Agents as workers, not as the platform
- AI engineering framework used daily by a product team
- Durable jobs for long-running work
- Persistent sessions and a web interface to follow and steer them
Ezlo 2026–now · Independent contractor 2018–now · Local AI platform …Ezlo 2026–now · Independent contractor 2018–now · Local AI platform · PRD + SIM
- MCP2026–now
MCP gateways and clients, shell tooling for running MCP API calls, automatic discovery of MCP servers with automatic (re)connection, and validation of API calls before they are sent. A small tool-calling model inside the gateway answers an AI's wrong call with a reasonable "did you mean…".
- Automatic discovery of MCP servers, with automatic (re)connection
- MCP clients and shell tooling for running MCP calls from scripts
- MCP gateways: many servers behind one endpoint
- Small tool-calling model in the gateway suggesting "did you mean…" for wrong calls
- Validation of calls before they are sent
Ezlo 2026–now · Local AI platform
- Self-hosted LLMs2025–now
Running models on our own hardware with llama.cpp, vLLM, Ollama and similar, on a single GPU or a stack of them, for myself and for companies I help. I also built managers that queue requests and schedule the models: when not all models fit in memory, they start and stop vLLM, llama.cpp or whatever serves a model, dynamically, based on what is in the queue, its priority and other rules set in the manager.
- llama.cpp, vLLM, Ollama and similar inference servers
- Managers that queue requests and schedule the models
- Models assigned by workload: large reasoning, vision, speech, small supervisors
- Models started and stopped dynamically when they don't all fit in memory
- Scheduling by queue contents, priority and configurable rules
- Single-GPU set-ups and multi-GPU stacks, for myself and for clients
Local AI platform
- Small task models (Needle 3)2026
Small task- or domain-specific models that turn plain input into API calls: inside web apps, mobile apps and command-line tools, they act as a mini harness that parses user commands, internal API requests or another script's output and maps them to the right call. Fully offline, in the browser or on the phone.
- Fully offline: in the browser tab or on the phone
- Inside web apps, mobile apps and CLI tools
- Mapping internal API requests or another script's output to the right call
- Parsing user commands into an app's API calls
- Small task-specific and domain-specific models
Offline model
- Whisper / Piper (voice)2018–now
A local voice assistant: wake word, speech-to-text, a model and text-to-speech, all on my own hardware.
- A model in between, all running locally
- Text-to-speech (Piper)
- Wake word and speech-to-text (Whisper)
Independent contractor 2018–now
Browsers, devices and embedded
- Android / ADB2026
Access to the phone's back end: clean-up and optimization, and full control of Android phones, like headless Chromium for the browser. Automated tests, app discovery, app reverse engineering and traffic inspection with a man-in-the-middle proxy.
- App reverse engineering
- Automated tests and app discovery
- Full remote control of phones
- Phone clean-up and optimization
- Traffic inspection through a man-in-the-middle proxy
Local AI platform
- Android apps2025–now
Custom Android apps for statuses, reservations, notifications and reading, and many clients for cloud services, built with Jetpack Compose, motion sensors, DataStore and ML Kit.
- Apps for statuses, reservations, notifications and reading
- Clients for cloud services
- Jetpack Compose, sensors, DataStore, ML Kit
Tilt to read
- Browser extensions and userscripts2026
Custom code for web applications we couldn't modify: depending on the environment, an extension, a Tampermonkey script or a reverse proxy injecting it. Many legacy apps were made to look nicer and run better this way, modernizing their UI step by step; also a debugging probe that runs inside live pages.
- Code injected where the app itself can't be changed
- Debugging probe running inside live pages
- Extension, userscript or reverse-proxy injection, by environment
- Legacy UIs modernized step by step
In-instance probe
- ESP8266 / ESP32 / Arduino (PlatformIO)2026
From small devices like motion sensors and speakers to home-automation devices and test harnesses that turn a physical device into an API: switching a server on and off, tripping a sensor to measure latency, reading the colours on a monitor, detecting states, weather. Built with PlatformIO and libraries such as IRremoteESP8266, ArduinoJson and LittleFS.
- Firmware updates triggered by publishing a URL over MQTT
- Home-automation devices: an IR bridge, a PC power watcher, a serial-to-Wi-Fi bridge
- Motion sensors, speakers and other small devices
- PlatformIO builds with IRremoteESP8266, ArduinoJson, LittleFS
- Switching servers on and off, tripping sensors to measure latency, reading monitor colours
- Test harnesses that make a physical device an API
IRBouncer
- Headless Chromium2025–now
An API-driven, MCP-capable Chromium with queues, per-domain throttling, sessions where a client leases a tab for a while with memory limits and automatic clean-up, and DevTools-protocol access to inject code. Used for scraping and for testing by AI and automated tools: comparing screenshots of a page after login with the Figma design, first by hand and scripts, now automated by AI. AI also explores a site or app, logs in, takes screenshots and documents every page into a map of all actions and paths, which becomes a skill for support and the source for manuals, videos and marketing material.
- AI exploration of a site or app into a map of every action and path
- DevTools protocol for code injection
- HTTP and MCP API in front of Chromium
- Leased tabs with memory limits and automatic clean-up
- Queues and per-domain throttling
- Screenshot comparison with Figma designs, now automated by AI
- Support skill, manuals, videos and marketing material generated from that map
Offline model · Local AI platform · PRD + SIM …Offline model · Local AI platform · PRD + SIM · Document index
- Home automation2026
With many systems and protocols: Home Assistant, Broadlink, Z-Wave, Zigbee and, more recently, Matter. Also reverse engineering smart-home devices and analysing their product details.
- Home Assistant, Broadlink
- Product analysis of devices
- Reverse engineering smart-home devices
- Z-Wave, Zigbee, Matter
IRBouncer
- Serial / USB devices2000–2003
Barcode scanners and other devices in desktop database applications, and microcontroller-driven rigs that automated hardware testing over HTTP and TCP.
- Barcode scanners in desktop applications
- Microcontroller rigs automating hardware tests over HTTP and TCP
Database applications 2000–2003
- VNC2026
A human-visible window into a container running something specific: recording what a headless app does on a virtual desktop, remote access, and watching a desktop while automating it.
- Human-visible window into containers
- Recording headless apps on a virtual desktop
- Remote access
- Watching a desktop while automating it
Local AI platform
Data and search
- Cassandra2018–2025
The data platform for heavy input and output, such as dumps of events and logs: raw data stayed in Cassandra, while processed and normalized data went to PostgreSQL or CockroachDB with indexes and better search. We also built a map-reduce engine: jobs that scan huge tables and copy filtered or transformed data into smaller ones.
- Heavy write and read workloads: events and logs
- Map-reduce engine: jobs scanning huge tables into smaller, filtered or transformed ones
- Multi-datacentre clusters
- Raw data in Cassandra, normalized data in PostgreSQL or CockroachDB
- Wrapper that routes queries to Cassandra or PostgreSQL/CockroachDB
Ezlo 2018–2025
- CockroachDB2018–2025
Distributed SQL, the next step from PostgreSQL: behind cloud services, with wrappers and migrations from Cassandra.
- Distributed SQL behind cloud services
- Migrations from Cassandra
- Wrappers shared by services
Ezlo 2018–2025
- CouchDB2014–2017
Multi-master sync for roaming clients that were offline for a while: a laptop application kept a partial copy and synced with the main server when online, with conflict resolution done first by a natural-language parser and later by AI. On a Kubernetes cluster, a CouchDB cluster held distributed locks: a service takes a lock on an API or a file, passes it to other services in calls, and they can extend or cancel it; during a network split across data centres, services could still get locks for data in their own data centre.
- Conflict resolution: first a natural-language parser, later AI merging
- Distributed locks on a Kubernetes cluster
- Laptop app with a partial copy, synced when online
- Locks passed between services, extended or cancelled
- Locks still available per data centre during a network split
- Multi-master sync for clients that go offline
Analysis and prototyping 2014–2017
- Debezium (change data capture)2018–now
Capturing changes from MySQL and legacy systems to help migrate the data to Cassandra, CockroachDB and PostgreSQL.
- Change capture from MySQL and legacy systems
- Custom connector image
- Migrations to Cassandra, CockroachDB and PostgreSQL
Independent contractor 2018–now
- InfluxDB2018–now
Time-series metrics, with workers that manage shards dynamically and workers that process and write the data.
- Time-series metrics
- Workers that manage shards dynamically
- Workers that process and write the data
Independent contractor 2018–now
- Meilisearch2026
Indexing documents and content, for tags and, with an embedding model, for vector search. Purpose-built indexes, one per use case: titles, titles plus summaries, and hybrid semantic search over documentation.
- Document and content indexing
- One index per use case: titles, titles plus summaries, documentation
- Tags and facets
- Vector search with an embedding model
Local AI platform · Document index
- MySQL / MariaDB2009–now
Behind almost every web system since 2009, from a MySQL cluster for sensor data to one database per microservice. Full-text search was even used as a tag filter: tags stored as short tokens like _t42 in one indexed column.
- Full-text search used as a fast tag filter with short tokens like _t42
- MySQL cluster for sensor data
- One database per microservice
- Web systems since 2009
Independent contractor 2018–now · Document index · MiOS 2013–2018 …Independent contractor 2018–now · Document index · MiOS 2013–2018 · Analysis and prototyping 2014–2017 · Sensor array system design 2012–2013 · Web projects 2010–2012 · Mobidev 2009–2010
- PostgreSQL2018–now
A great database that I've used a lot, especially its JSON support for metadata. It also served as a message queue: one query claims rows and assigns them to workers, with no transactions, for a large number of workers on large tables; used mainly to schedule work, with workers handing it to other queues when it's time to act.
- JSON columns for metadata
- Main database for many services
- Many workers at once on large tables
- Message queue: one query claims and assigns rows to workers, no transactions
- Scheduling work that is later handed to other queues
- Shared database wrapper with pooling and retries
Independent contractor 2018–now · GoDaddy 2018
- Search gateways (SearXNG)2026
Customized search inside a company: like the many specialized indexes of a distributed document system, it gives one entry point where you type what you need and it runs the searches. Sometimes with adapters that classify and reorder the results, sometimes returning them directly; also a self-hosted metasearch back end for AI research agents.
- Adapters that classify and reorder results
- One search box over many specialized searches
- Self-hosted metasearch for AI research agents
Local AI platform
- SQLite FTS52018–now
A local database with full-text search for clients and scripts that need their own copy to query and search: much faster than storing files and running grep over them. Every AI session transcript, for example, is indexed and searchable by message, session or file.
- AI session transcripts searchable by message, session or file
- Full-text search instead of files and grep
- Local database for clients and scripts
Independent contractor 2018–now
Infrastructure
- Docker2016–now
Since 2016, for every service since. One unusual set-up: on-demand workers for Docker Swarm on servers with no disks. They net-booted Alpine Linux, found the swarm, joined it and took workloads, and were shut down when the work stopped; everything was mounted over the network or copied into memory at run time. It is also a developer tool: run several versions of Node.js, PHP, Python or Bash, in any combination, and test how the software behaves on exactly those versions without reinstalling anything on the developer machine; the same set-up serves for cross-compiling.
- Cross-compiling
- Desktop Linux applications running in containers
- Developer environments: any combination of Node.js, PHP, Python and Bash versions
- Diskless Docker Swarm workers: net-boot Alpine, join, work, shut down
- Every service since 2016
- Everything mounted over the network or copied into memory
- Testing on exact versions without reinstalling the developer machine
- Tool that converts a Dockerfile into an LXC install script
Independent contractor 2018–now · Local AI platform · Document index …Independent contractor 2018–now · Local AI platform · Document index · Ezlo 2018–2025
- File synchronization2018–now
Two-way and multi-node file sync: Unison for bidirectional sync between two machines, Syncthing for continuous multi-node sync, and rsync for one-way copies and backups.
- rsync: one-way copies and backups
- Syncthing: multi-node, continuous
- Unison: bidirectional sync
Independent contractor 2018–now
- Git / Gitea / GitLab2026
As a client and as a host, with scripts that sync repositories across nodes, in a cluster or between independent nodes that want a replica for backup. A lot of work with webhooks and CI/CD pipelines, and with local hooks before or after a commit for code review, linting and tests.
- Client and self-hosted server (Gitea, GitLab)
- Documentation and graphs kept next to the code they describe
- Pre- and post-commit hooks: code review, linting, tests
- Repository sync across nodes, clustered or independent
- Webhooks and CI/CD pipelines
Local AI platform
- Kubernetes2018–now
Platform environments: namespaces per environment, probes, cron jobs, ingress and single sign-on, with autoscalers generated from the service manifests and configuration overrides from ConfigMaps that services pick up without a restart.
- Autoscalers generated from service manifests
- ConfigMap overrides picked up without a restart
- Namespaces per environment
- Probes, cron jobs, ingress, single sign-on
Independent contractor 2018–now · Document index · Ezlo 2018–2025
- Linux2006–now
Servers and desktops since 2006; today Ubuntu and Debian, plus desktop distributions for GPU and CPU workloads.
- Desktop distributions for GPU and CPU workloads
- Servers and desktops since 2006
- Ubuntu and Debian today
Local AI platform · Exig0 2006–2009
- LXC2026
A mature, older container system, usually through Proxmox, used for everything from servers to desktop applications in a container.
- Isolation for browser automation and agent workloads
- Mature container system, usually through Proxmox
- Servers and desktop applications in containers
Local AI platform
- pfSense / MikroTik2018–now
Network set-up and management: installation, configuration, networks, VLANs and firewall rules, with NAT rules kept in sync from code through the RouterOS API.
- Installation and configuration
- NAT rules synced from code through the RouterOS API
- Networks, VLANs and firewall rules
Independent contractor 2018–now
- Raspberry Pi2012–now
Since the first 256 MB model: print servers, UPS monitors, cameras, terminal devices with keyboards, edge cluster nodes and VPN endpoints, and home-automation edge nodes that handle local radios and route their data to cloud and remote servers with ser2net, socat and Docker. Many run on read-only disks, so too many writes can't wear the card out.
- Edge cluster nodes and VPN endpoints
- Home-automation edge nodes with local radios, routed with ser2net, socat and Docker
- Phones exposed as an API over adb
- Print servers, UPS monitors, cameras, terminal devices
- Read-only disks to survive write wear
- Since the first 256 MB model
Local AI platform
- tinc (mesh VPN)2018–now
Mesh VPN between roaming clients, for backups, remote connections and site-to-site links; in one set-up one of the sites was a van with servers that monitored environmental data.
- Backups and remote access
- Mesh VPN between roaming clients
- Site-to-site links, one site being a van with monitoring servers
Independent contractor 2018–now
- WireGuard2018–now
Remote access to services from Android, Windows and Linux phones, tablets and laptops, with the connection started and dropped automatically depending on which apps are running, and split DNS so names resolve through the tunnel or outside as needed.
- Connection started and dropped automatically by running apps
- Remote access from phones, tablets and laptops (Android, Windows, Linux)
- Split DNS: through the tunnel or outside
Independent contractor 2018–now
- ZFS2012–now
Since 2012, first as a NAS replacement and then, for its resilience, ease of use and good tooling, for main storage, backup storage, synchronization and snapshots in many set-ups.
- Main storage and backup storage
- Pool status monitoring
- Replication between sites and snapshots
- Since 2012, first replacing a NAS
Independent contractor 2018–now
Languages
- Bash / Zsh2006–now
Bread and butter: Bash since 2006 and Zsh since around 2015, where I fell in love with Oh My Zsh and install it everywhere; for build, deploy and operations scripts, image builds, registry pushes, deploy webhooks, and setup, start, stop and status scripts for every tool.
- Bash since 2006, Zsh since around 2015
- Build, deploy and operations scripts
- Compliance checker that verifies every tool in a framework ships the required files
- Image builds, registry pushes, deploy webhooks
- Oh My Zsh on every machine I use
- Setup, start, stop and status scripts for every tool
Independent contractor 2018–now
- C / C++ (microcontrollers)2012–now
Learned in school, used mostly on Arduinos, ESPs and other microcontrollers to build devices, mainly for home automation and for testing physical things end to end. One test rig tripped a door/window sensor from an Arduino pin and measured the real time from the hardware event, over Z-Wave to the hub, to the cloud, the database and finally the notification.
- An 8 KB loop stack and a watchdog as design constraints: large payloads parsed on the heap
- Custom ATmega2560 boards with W5100 Ethernet for a 6,000-sensor array (256 KB flash, 8 KB RAM, 16 MHz)
- End-to-end latency rig: an Arduino trips a door sensor, timing hub → cloud → database → notification
- ESP8266/ESP32 firmware with PlatformIO
- Native unit tests with mocks for firmware
- Safe mode after repeated crash boots, so a device on the ceiling stays reachable
IRBouncer · Sensor array system design 2012–2013
- Go2018–now
Where I end up when something has to be efficient, slim and easy to ship. I prototype in PHP, Python or Node.js, sometimes close to a final product, then port it to Go when it needs to run lean; I rarely start in Go unless I know from day one that it's needed.
- Agent of a GPU platform: monitoring, admission control, supervision
- Prototype first in a language with no compile step, port to Go when it must be lean
- Single static binaries: easy to deploy and copy between machines
- Small MCP server and a command-line tool for a graph file format
Independent contractor 2018–now
- JavaScript / CSS2006–now
From plain HTTP pages with iframes and a little JavaScript that had to work in Internet Explorer 6, through the jQuery years, to modern browser scripting where AI models now run inside the tab. Every simulation and demo on this site is plain browser JavaScript and CSS, with no build step.
- Debugging probe designed to run inside a live page's own code
- Modern browser scripting: Web Workers, WebAssembly, AI models running in the page
- Shop front ends built for Internet Explorer 6: plain pages, iframes, a little JavaScript
- The jQuery years: interactive web apps and portals
- Whole interactive product specs as single HTML files, no build step
Offline model · GoDaddy 2018 · Exig0 2006–2009
- Kotlin (Android)2018–now
An Android e-book reader with tilt-to-scroll: tilting the phone scrolls the text, the angle sets the speed, with acceleration, debounce and configurable zones. See the tilt demo and the showcase.
- Acceleration curves, debounce and configurable zones
- Android e-book reader in Kotlin
- Live demo: tilt to read
- Presets shared between phones as QR codes
- Tilt-to-scroll: the angle sets the speed
Independent contractor 2018–now · Tilt to read
- PHP2006–now
My longest-running language: e-commerce and multi-shop payment platforms with direct bank integrations, white-label web portals for many OEM brands from one code base, and the migrations of a large web platform from PHP 4 to 5.2, later to 7.0 and now 8.0. On a couple of projects it was also the main scripting and automation language, shipped with its own PHP binary so the same scripts ran on Linux, Unix, macOS and Windows without a system-wide install.
- API aggregator that replaced a slow mobile app's many calls with one request, streaming newline-delimited JSON back
- E-commerce and multi-shop payment platforms with direct bank integrations
- On a couple of projects, the main scripting and automation language across Linux, Unix, macOS and Windows, with the PHP binary shipped inside the package
- Parser turning zfs/zpool status output into monitoring data
- Platform migrations from PHP 4 to 5.2, later to 7.0 and now 8.0
- RouterOS API wrapper that keeps router NAT rules in sync from code
- Search aggregator querying several engines in parallel with curl_multi, merged behind a caching proxy
- White-label web portals: many OEM brands served from one code base
Independent contractor 2018–now · GoDaddy 2018 · MiOS 2013–2018 …Independent contractor 2018–now · GoDaddy 2018 · MiOS 2013–2018 · Analysis and prototyping 2014–2017 · Sensor array system design 2012–2013 · Web projects 2010–2012 · Mobidev 2009–2010 · Exig0 2006–2009
- Python2015–now
Glue, mostly: test harnesses, benchmark scorers, data clean-up, classification scripts and format converters. With AI now writing a lot of Python, I'm also learning a lot from the code it produces.
- Data clean-up and classification scripts
- Format converters, e.g. importing third-party IR code libraries into my firmware's format
- Glue between systems and formats
- Reviewing and learning from the Python that AI writes
- Test harnesses and benchmark scorers
Ezlo 2026–now · Local AI platform · GoDaddy 2018
- TypeScript2018–now
The next level of JavaScript for Node.js: I learned it to build things that needed it and to use the TypeScript libraries that solve many problems well. Agent extensions, an MCP gateway, a conversation graph and an OpenAI-compatible API in front of a command-line agent.
- Agent extensions, an MCP gateway, a conversation graph
- Often run directly as .ts, with no build step
- OpenAI-compatible API in front of a command-line agent
- Typed JavaScript for larger Node.js code bases
- Using TypeScript-first libraries where they are the best option
Independent contractor 2018–now
- Visual Basic2000–2006
Visual Basic 6 database applications with custom flows for different businesses, talking to barcode scanners and other devices over serial and USB; then the Windows successors of DOS accounting software.
- Barcode scanners and other devices over serial and USB
- Visual Basic 6 database applications with custom flows per business
- Windows successors of DOS-era accounting software
Accounting software 2003–2006 · Database applications 2000–2003
Messaging and APIs
- JSON / YAML2026
Everywhere from configuration to transport in APIs and queues. Two special cases: YAML front matter in Markdown files, which records when a document was created and by whom, and JSON Lines, one JSON object per line, used for streaming: instead of one huge JSON over a WebSocket, complete parts are sent and the client assembles them, which also lets several APIs multiplex data over one connection.
- Configuration files and data
- JSON Lines for streaming partial data that the client assembles
- JSON Schema for tool definitions generated from live data
- Payloads in APIs and queues
- Several APIs multiplexed over one WebSocket
- YAML front matter in Markdown: who created a document and when
Offline model
- Kafka2018–now
Pipelines and queues for microservices, mostly where messages need to be re-read, resumed or consumed by several consumers; whether Kafka or RabbitMQ was used depended on the profile of each use case.
- Autoscaling generated per consumer from the service manifests
- Change data capture from Cassandra into Kafka
- Pipelines between microservices on a platform of 900+ microservices
- Queues that need replay, resume or several consumers
- Shared consumer library: dead-letter queues, commit strategies, batching
Independent contractor 2018–now · Ezlo 2018–2025
- MQTT2012–now
Since 2012, in many roles: transport for thousands of sensors, live events between services, a discovery medium where services broadcast their status, a transport proxy for HTTP requests, and state storage with retained messages for home automation, cloud and edge services. I also built brokers with optimizations ordinary brokers don't have, such as watching specific topics or a last will that works differently.
- Clustered brokers, and MQTT used as an RPC interface with confirmations and retry/replaced states
- Custom brokers optimized for specific payloads: topic watchers, a different last-will behaviour
- Live events between services
- Service discovery: services broadcast their status
- State storage with retained messages, for home automation, cloud and edge services
- Transport for thousands of sensors
- Transport proxy for HTTP requests between services
IRBouncer · Document index · Ezlo 2018–2025 …IRBouncer · Document index · Ezlo 2018–2025 · MiOS 2015–2018 · Analysis and prototyping 2014–2017 · Sensor array system design 2012–2013
- NATS2018–now
Used in a couple of projects, including one that ran dynamic workloads defined as lambdas, where all communication between the nodes went over NATS.
- All communication between nodes over NATS
- Lambda platform: dynamic workloads defined as lambdas
- Messaging in a couple of projects
Independent contractor 2018–now
- OpenAPI contracts2026
The standard way to define an API: what it accepts and how it answers a standardized call. Many projects also accepted several endpoint formats, for easier integration with different clients and third parties; one system has 19 capability contracts that independent modules implement and discover through a registry.
- 19 capability contracts implemented by independent modules and discovered through a registry
- API definitions as OpenAPI contracts
- Several endpoint formats accepted for different clients and third parties
- Standardized calls and answers
Document index
- Payment gateways2006–2012
Direct bank integrations, PayPal and Google Wallet in e-commerce and multi-shop platforms.
- Direct bank integrations
- E-commerce and multi-shop platforms
- PayPal and Google Wallet
Web projects 2010–2012 · Exig0 2006–2009
- RabbitMQ2014–now
Highly available queues and temporary queues for large commerce platforms and on Kubernetes, sometimes instead of Kafka and sometimes alongside it: the right queue was chosen by the workload, how it scales and how fast it has to scale.
- Highly available queues for large commerce platforms
- On Kubernetes, instead of or next to Kafka
- Queue chosen by workload and scaling profile
- Quorum queues as the cluster-wide default, behind HAProxy
- Temporary queues for short-lived work
Independent contractor 2018–now · Ezlo 2018–2025 · Analysis and prototyping 2014–2017
- WebSockets2015–2018
Live connections everywhere: edge devices, home-automation hubs, ESP32 and Arduino devices, servers and the browser. Live dashboards and device control, MQTT over WebSockets instead of long polling, and streaming APIs where several APIs share one connection.
- Edge devices and home-automation hubs
- ESP32 and Arduino devices
- Live log streaming
- MQTT over WebSockets instead of long polling
- Servers and browsers
- Streaming APIs with several APIs multiplexed over one connection (JSON Lines)
MiOS 2015–2018
Observability
- Grafana / Loki / Prometheus / Tempo2018–now
Storing and viewing telemetry, logs, metrics and traces, both using it and setting the whole stack up.
- Dashboards in Grafana
- Logs (Loki), metrics (Prometheus), traces (Tempo)
- Using it and setting it all up
Independent contractor 2018–now
- Jaeger / Zipkin2018–now
OpenTelemetry receivers for local development: run the services in containers and see what they expose, with flame graphs, without deploying anything to the cloud to get readable telemetry.
- Flame graphs for local debugging
- No cloud deployment needed to see traces
- OpenTelemetry receivers on a developer machine
Independent contractor 2018–now
- OpenTelemetry2018–now
Tracing on the Ezlo platform and in contract work. To keep services light, they didn't carry the full Node.js OpenTelemetry stack: a small library sent the same OpenTelemetry payloads as UDP messages, and a gateway collected them and forwarded them in bulk over WebSocket or HTTP. That decoupled 900+ microservices from the endpoint: no buffers, no connection handling, just fire and forget, with the least performance impact.
- 900+ microservices decoupled from the telemetry endpoint
- Gateway collecting UDP and forwarding in bulk over WebSocket or HTTP
- No per-service buffers or connection handling: fire and forget
- Small library sending OpenTelemetry payloads over UDP instead of the full SDK
- Tracing across services on the Ezlo platform and in contract work
Independent contractor 2018–now · Ezlo 2018–2025
Product and method
- Decision logs2025
Documentation that keeps the why, who, when and what, not only the result: what we tried, why it didn't work or wasn't liked. AI now uses it too, skipping ideas we documented as tried and rejected, like an API that wasn't fast enough or a library that wasn't good enough.
- AI reads it and skips ideas already rejected
- Conditions under which a rejected idea could come back
- Tried and rejected alternatives, with the reason
- Why, who, when and what for every decision
PRD + SIM
- LaTeX2018
Used at GoDaddy.
- Used at GoDaddy
GoDaddy 2018
- Markdown2013–now
The de facto standard of my documentation: easy to read, move around and convert into something else, easy to turn into an HTML page, and readable by AI.
- Easy to read, move and convert
- Main documentation format
- Readable by AI
- Turned into HTML pages
Local AI platform
- Product documentation (PRDs + SIMs)2025–now
Documentation from the first client request or stakeholder idea, from the napkin, to the documented final result. The key addition: single-page HTML simulations of the PRD or technical spec, which turn hundreds of pages of technical data and use cases into something you can see before anything is built. Instead of months of development before finding out it isn't what the stakeholder wanted, we meet over a simple simulation, iterate fast and update the documentation at the end: fast feedback for stakeholders, a demo for engineering, and a head start for marketing.
- A demo for engineering and a head start for marketing
- AI-assisted review and role-based sign-off
- Fast iteration with stakeholders in a meeting
- From the first request or idea to the documented result
- Hundreds of pages of use cases made visible before anything is built
- Single-page HTML simulations of PRDs and technical specs
Ezlo 2026–now · PRD + SIM
- Task management apps2026–now
Day-to-day management of work in task-based apps: Jira for tickets, from DevOps tasks to tasks and epics, and Confluence for documentation; reviews and planning with different methodologies, agile included, and prioritization with ICE and RICE.
- Agile and other methodologies
- Confluence for documentation
- Connected to AI agents through tools
- Jira for tickets: DevOps tasks, tasks, epics
- Prioritization with ICE and RICE
- Reviews and day-to-day planning
Ezlo 2026–now
Runtimes and frameworks
- Bun2018–now
An equivalent of Node.js and Deno for some tasks: I pick Node.js, Deno or Bun by what each job needs, since each is good at different things.
- Benchmarked on the same HTTP and database workloads
- Chosen per task next to Node.js and Deno
Independent contractor 2018–now
- CodeIgniter2010–2012
From 2010–2012, possibly earlier: many applications started on CodeIgniter, with changes that made the framework easier to extend. Most of them still run today on the latest PHP, thanks to an injected library that re-implements functions newer PHP versions removed, with the same calls; a couple of them work unchanged apart from that library.
- A couple of apps unchanged apart from that library
- Compatibility library injected to replace functions removed from newer PHP, same code
- Framework changes to make it easier to extend
- Many applications built on CodeIgniter from around 2010
- Still running today on the latest PHP
Web projects 2010–2012
- Deno2018–2025
Sandboxes: user-configured if-then-else conditions and actions were converted in the back end into JavaScript, evaluated and kept running as a service. Deno's permissions kept that code from doing what it shouldn't, and it usually ran inside Docker as well: several layers of isolation so nothing could escape.
- Compared with isolated-vm and vm2 sandboxes for untrusted code
- Deno permissions: no access beyond what each script needs
- Generated code evaluated and kept running as a service
- Inside Docker as a second layer of isolation
- User-configured conditions and actions turned into JavaScript in the back end
Ezlo 2018–2025
- Express / Fastify2018–now
HTTP services with Express and Fastify, in deployments that served more than 10,000 requests per second, with instances scaled out usually on Kubernetes and also on Docker Swarm.
- Benchmarks of Express against Fastify and bare handlers
- Deployments serving more than 10,000 requests per second
- HTTP services on Express and Fastify
- Scaled out on Kubernetes, and on Docker Swarm
Independent contractor 2018–now
- jQuery2010–2012
Front ends of the 2010s web projects.
- Front ends of the 2010s web projects
Web projects 2010–2012
- Node.js2012–now
Services and tools since 2012: live monitoring endpoints for a sensor array, broker clusters and job queues, cloud services at platform scale, and most of my own tools today.
- Cloud services at platform scale
- Clustered MQTT broker that handled network splits and rejoins
- Event-loop benchmarks under simulated latency (30 ms, 500 ms) across frameworks and runtimes
- Live monitoring endpoints for a 6,000-sensor array (2012)
- Most of my own tools today
Ezlo 2018–now · Independent contractor 2018–now · Local AI platform …Ezlo 2018–now · Independent contractor 2018–now · Local AI platform · Document index · MiOS 2015–2018 · Analysis and prototyping 2014–2017 · Sensor array system design 2012–2013
- Symfony2010–2012
Web application architecture for client projects.
- Web application architecture for client projects
Web projects 2010–2012
- WebAssembly2026
Workers and a lot of fancy things in the browser, and lately AI agents that run inside the tab: a 35 MB tool-calling model in one HTML page, with no server.
- 35 MB tool-calling model in a single HTML page, no server
- AI agents running inside the tab
- Web Workers and WebAssembly for heavy work in the browser
Offline model
- Zend2010–2012
Web application architecture for client projects.
- Web application architecture for client projects
Web projects 2010–2012

