Explore our latest articles, guides, and thoughts on digital strategy, design, and development.
Every AI crawler my robots.txt invited was being served an unreadable blob. It returned 200. It had the right content-type. It was gibberish, and I found it by accident.
August 10, 2026
Response times swung between 0.3 and 11.5 seconds on serverless Postgres. Every instinct said query tuning. The proof came from timing an endpoint that never touches SQL.
August 3, 2026
A database outage rendered in the app as 'No providers near you' β at HTTP 200, with nothing to alert on. The fix needed zero client changes, because of how the parser fails.
August 3, 2026
The bug report was 'random black flashes on mobile'. It was a GPU context loss the page could never recover from β hiding under a HUD that kept painting perfectly.
July 31, 2026
Chat messages were writing successfully and no client on Earth could see them. The rule was on the message; onChildAdded listens on the list.
July 26, 2026
Adding orderBy('createdAt') to a collection containing documents written before that field existed made every one of those documents disappear from the results. Status 200. No error. Just fewer recipes.
May 24, 2026
A snapshot of the outcomes we build toward: faster response times, fewer manual handoffs, cleaner systems, and better visibility across the business.
A Next.js and Firebase platform that audits a site with real crawls and Gemini analysis, and labels every result with how it was produced β measured, estimated, or simulated β so you can tell an actual measurement from a model's guess.
Result:
~184,000 lines of TypeScript; 95 pages, 106 API routes, 19 Cloud Functions
Practical feedback from teams using the systems, workflows, and digital products we help design and deliver.