Writing

Notes on shipping.

Things I've learned by doing, mostly about infrastructure, systems design, and the realities of running production as one person. Published when I have something specific to say.

No ads. No sponsors. No AI-generated filler. Everything here came out of real work.

Seventeen Cloud Functions codebases is not an architecture

Planning the consolidation of ~17 independently-deployed gen-1 Firebase Functions into one backend: the cold-start case, what stays behind, what you lose with per-function deploys, and the middleware debt it finally forces you to pay.

#firebase#serverless#architecture
→

Cloudflare Pages 308-redirects your no-slash URLs — make canonicals match TIL

→

GSC "Sitemap could not be read" is usually transient — curl as Googlebot before panicking TIL

→

The real cost of a proper staging tier for a 12-service product

Mirroring a production platform — Workers, databases, queue brokers, OAuth, messaging providers, voice tooling — into an isolated dev environment took weeks, not days. Here is every trap that made it so.

#staging#devops#coolify
→

Building an OIDC provider on Cloudflare Workers so two products share one login

Why we built a first-party OIDC/SSO provider — PKCE, RS256, JWKS, single-use codes in Postgres — instead of buying one, and the code-consumption ordering bug review caught before launch.

#auth#oidc#cloudflare-workers
→

My $0 Infrastructure Stack: Cloudflare, Coolify, Neon, Resend and a Laptop in My Office

The complete architecture behind my prototypes, production apps, and trading bots — Cloudflare, Coolify, Neon, R2, and two i7 laptops that were gathering dust. Including the free-tier ceilings, the backup strategy, and what I refuse to self-host.

#infrastructure#self-hosted#cloudflare
→

Finding the money leaks: unit economics is observability

We lined up provider spend against billed usage on an AI platform and found a per-minute telephony cost that was being paid but never charged to anyone. How to instrument costs so leaks show up as data, not as a bad month.

#billing#unit-economics#operations
→

Encrypting production tokens in place, without downtime

Retrofitting encryption at rest onto live third-party tokens across Postgres and KV: per-surface keys, key versioning for rotation, one-time backfills, and the wrangler stdout bug that nearly polluted the audit.

#security#cloudflare#operations
→

Trace every visible surface back to its data source

During a billing migration, one customer's balance widget showed -1 while their real balance was fine — because one endpoint still read the orphaned old column. The rules I now follow on every data migration.

#migrations#debugging#process
→

Repricing a live SaaS: the data-normalization checklist nobody gives you

Changing your pricing model is easy on a whiteboard. The real work is normalizing every existing customer, both payment modes, every tier reference in code, and the leftover limits that bite weeks later.

#billing#stripe#migrations
→

Changing prices in Stripe without breaking existing subscriptions Tutorial

Stripe Prices are immutable — you don't edit them, you replace them. Here's the repricing pattern that keeps every existing agreement intact: new Prices, archived old ones, and contract versioning with pricing snapshots so history stays auditable.

#stripe#billing
→

Self-hosting an email client on Cloudflare Workers Tutorial

How I run a full email client for my own domains on Cloudflare's free tier: Email Routing delivering inbound mail into a Worker, a forked open-source client, multi-provider outbound sending, and a bring-your-own-key AI drafting feature.

#email#cloudflare-workers#self-hosted
→

Free professional email on your own domain: Cloudflare inbound, Resend outbound

Leaving Namecheap hosting, the one thing I couldn't figure out was my professional email. Here's how I got a full self-hosted email client — inbox, sending, storage — for $0 using Cloudflare Email Routing, Workers, and Resend.

#infrastructure#self-hosted#cloudflare#email
→

I lost $800 to trading bots, so I built one where the risk limits require a code edit

I bought commercial scalper bots, disabled their loss limits, and paid for it. The bot I'm building instead has a Risk Cage: six catastrophic-stop circuits that cannot be toggled off from any settings screen.

#trading#risk#side-projects
→

When your docs lie: CLAUDE.md drift and the mock payment that reached production

Docs are code that never runs, so nothing tells you when they rot. Two cases from my own projects — an agent-facing doc describing a system that no longer existed, and an audit that found a dev-only payment stub still live in prod.

#documentation#ai-workflow#maintenance
→

One prompt, one blank directory, one trading platform

I gave an AI agent an empty folder and a vision for an XAU/USD trading-analysis system, then mostly watched. What a multi-hour autonomous build actually produced, what held up, and where this mode stops being appropriate.

#ai-workflow#trading#autonomy
→

Claude drove a Windows VM so I could use a Windows-only API on a Mac

MetaTrader 5's Python API only runs on Windows. I run an M2 Mac. The fix: Windows 11 in VirtualBox on Apple Silicon — with an AI agent doing the setup, the testing, and the debloating inside the VM.

#ai-workflow#trading#virtualization
→

Scoping a platform rework from a requirements PDF

A client sent a requirements document for a major billing-model change. Before quoting, I had an AI agent decompose it against the real codebase — and the estimate came out of the delta, not the gut.

#ai-workflow#estimation#fractional-cto
→

The two-hour proposal prototype

Instead of writing a better Upwork proposal, I built a working demo of the thing and sent the live link. What that costs now, what it signals, and how to scope a prototype into two hours.

#freelancing#prototyping#ai-workflow
→

My PR pipeline: two AIs review each other and I referee

Every non-trivial PR gets an automated review, then a counter-review from a second model told explicitly not to trust the first, then persona passes — and my job shifts from reading diffs to judging findings.

#ai-workflow#code-review#process
→

Ten read-only agents and a critic: auditing a billing system before touching it

How I map a legacy subscription system spanning four codebases before changing a line of it — a fleet of parallel read-only AI agents, one 'completeness critic', and a rule that nothing writes anything.

#ai-workflow#architecture#billing
→

Building a booking system where Stripe doesn't exist

I own hotels in northern Pakistan, and I'm building their booking platform myself. No Stripe, flaky mountain internet, WhatsApp as the real communication channel — payment infrastructure looks very different from outside the countries it was built for.

#payments#pakistan#product
→

How to free up disk space on a Mac as a developer Tutorial

Where developer disk space goes—Xcode DerivedData, Gradle, node_modules, Docker—and how to clean it safely by hand or with reclaim, an open-source CLI.

#macos#developer-tools#open-source#tooling
→

Mirroring a production database into Google Sheets with no SDK Tutorial

A legacy PHP app with vendored libraries, no Composer, on cPanel — and a client who wanted live data in Google Sheets. The answer: raw Sheets REST calls, a hand-signed service-account JWT, and a two-layer sync design that can never break the app.

#google-sheets#php#integrations
→

Un-merging a feature without rewriting shared history Tutorial

A tester needed four features tested — without the unfinished fifth that was already merged into the same dev branch. Force-push was off the table. Here's the surgical git recipe that worked, and when each alternative is the right call.

#git#process
→

Firebase has no transaction spanning Auth and Firestore — order your writes for it TIL

→

Why I moved my agency's site off Firebase

Firebase Hosting is a fine product with a pricing model that stops making sense for static sites. The migration to Cloudflare took one working session — and left me with a deploy-safety rule I now apply everywhere.

#cloudflare#firebase#costs
→

Cloudflare Pages can show you a stale build — check the deployment before debugging your code TIL

→

git checkout <sha>^ -- <path> removes one feature without rewriting history TIL

→

I cloned a client's entire production stack onto a laptop in my office

Frontend, backend, PDF microservice, Redis, Elasticsearch — a full e-commerce platform mirrored onto a Lenovo i7 running Coolify behind Cloudflare Tunnel, as an isolated staging environment that costs nothing to run. Here's what actually broke.

#self-hosted#coolify#staging
→

Your dashboard's log export row cap can invert your priorities TIL

→

staleTime: 0 means refetch on every mount — and push-backed data doesn't need it TIL

→

How to use multiple Claude Code accounts — one per project Tutorial

Run multiple Claude Code accounts side by side with CLAUDE_CONFIG_DIR — manually, or automatically per project with csm, a free open-source session manager.

#claude-code#ai#tooling#open-source
→

Your marketing site is the fossil record of your product's first architecture

ChiroSimple's WordPress site wasn't just a marketing site — it was the original SaaS, a 245-sub-site multisite where every customer once had their own subdomain. Migrating it down to a single clean site meant database surgery, WP-CLI forensics, and a PHP time machine.

#wordpress#migrations#legacy
→

Elasticsearch timeouts change when you put a tunnel in the path TIL

→

wrangler's update banner goes to stdout and can poison your scripts TIL

→

An AI support chatbot on WordPress for about $0 Tutorial

How I built a knowledge-base-grounded support assistant into a WordPress marketing site using OpenRouter's free models — including intent classification, prompt-extraction guardrails, cost tracking, and the feedback loop that makes the KB smarter over time.

#wordpress#ai#support
→

The MetaTrader5 Python package is Windows-only TIL

→

Validate uploads by magic bytes, not file extension TIL

→

One non-const IconData ships every icon glyph in your Flutter app TIL

→

Adding AI to a bootstrapped SaaS: do the free-tier math first

Before building an AI feature on a self-funded product, compute the cost per unit of work. The arithmetic for AI-drafted visit notes across Cloudflare Workers AI, OpenRouter, Groq, and Gemini free tiers.

#ai#bootstrapping#unit-economics
→

On Cloudflare Workers, Prisma memory is set by peak concurrency — forever TIL

→

firebase deploy --only hosting ships every site in the project TIL

→

The compliance claim we deliberately didn't make

We set out to put 'HIPAA compliant' on an EHR's marketing site. The research said HIPAA doesn't even apply — and the honest answer turned into better positioning than the badge would have been.

#healthcare#compliance#positioning
→

Behind Cloudflare, HTTPS on the origin can cause redirect loops TIL

→

A Cloudflare Queue has exactly one consumer mode at a time TIL

→

When to retreat from an upgrade

A dependency upgrade broke production calendars, and rolling it back meant un-upgrading two other packages that pinned it. On the underrated engineering skill of strategic retreat.

#flutter#dependencies
→

NODE_ENV=development on your build server silently breaks builds TIL

→

Coolify injects build-time env vars as raw Dockerfile ARG lines TIL

→

Zero egress fees change which day your backup provider gets paid — R2 vs S3 TIL

→

Cutting 3.7 MB of icon fonts to 48 KB Tutorial

How a Flutter framework upgrade exposed that we were shipping ~7,447 icons to use 52 of them — and the two-stage fix that got a vendored icon font from 1.22 MB down to 3.8 KB.

#flutter#app-size#performance
→

tsc exit code 0 does not mean your typecheck passed TIL

→

inlineStylesheets: 'always' removes Astro's render-blocking CSS requests TIL

→

The 137,138-byte PNG that was actually JSON

A production PDF bug that traced back through a misleading success log, a corrupted logo file, and a null-coalescing operator — and why I refuse to trust a fix until it has been run against every row of production data.

#debugging#flutter#firebase
→

Astro's sitemap integration stamps lastmod on every URL with one config line TIL

→

Rate limiting behind Netlify Functions silently collapses without x-nf-client-connection-ip TIL

→

Hybrid Cloudflare: request path on Workers, heavy consumers on a cheap box

Cloudflare Queues supports HTTP pull consumers — which means your queue workers don't have to live in a 128 MB Worker at all. How we moved billing and evaluation consumers to Node processes on a Hetzner server, and what stayed behind.

#cloudflare#self-hosted#architecture
→

On serverless, run database migrations at deploy time — never at boot TIL

→

Express 5 + serverless-http can leave req.body in three different broken states TIL

→

Should you run Prisma on Cloudflare Workers in 2026?

An honest assessment from running a 180+ model Prisma schema on Workers in production: the WASM memory math, the transaction timeouts, what we tried, and when I'd do it again.

#prisma#cloudflare-workers#postgres
→

Stripe Prices are immutable — change pricing by minting a new Price and migrating at renewal TIL

→

Neon autosuspends idle databases — the first query after a quiet spell is slow, by design TIL

→

Never pipe user files through your serverless functions

How we accept 500 MB user uploads on a platform whose API runs in 128 MB Cloudflare Workers: presigned R2 URLs, a strict control-plane/data-plane split, and the one rule that keeps it safe.

#cloudflare-workers#r2#architecture
→

restic dedup makes nightly Docker-volume backups cost megabytes, not gigabytes TIL

→

Docker restart policies + a laptop battery survive power cuts with zero extra scripts TIL

→

Bad frontend state management can take down your serverless backend

On serverless platforms, the cost driver is how many requests run at once — and that number is decided in your React components. A production incident that proved burst width is architecture.

#react#cloudflare-workers#architecture
→

Coolify can manage a remote server — separate your control plane from your workloads TIL

→

Sending email from a Worker needs the paid plan — Resend's free tier fills the gap TIL

→

Why my first three root causes were wrong

Debugging production out-of-memory kills on Cloudflare Workers, I confidently blamed large payloads, an image gallery, and one heavy user. All three conclusions came from the same mistake: a truncated log export.

#debugging#observability
→

Cloudflare Email Routing can deliver into a Worker, not just forward TIL

→

The Worker was being killed 1,800 times a day. Here's why.

A production postmortem from Cloudflare Workers: 11,058 out-of-memory kills in a week, three wrong hypotheses, and a root cause that turned out to be a single React dependency array.

#cloudflare-workers#debugging#postmortem
→

Solo developer vs. agency: when each actually makes sense

The real tradeoff isn't cost — it's accountability shape. A plain-language guide for founders deciding which engagement model fits their next build.

#hiring#business
→

Hiring a HIPAA-compliant developer: what to actually look for

Most HIPAA compliance horror stories are hiring problems in disguise. Here's what I learned shipping a real EHR with 2M+ records — and what to ask candidates before you sign.

#healthcare#hiring#hipaa
→

The solo developer's infrastructure playbook

What changes about how you architect systems when there's no one else on the team. A short set of rules I live by.

#solo#infrastructure
→

How I turned a laptop into a production server

Coolify, Cloudflare Tunnel, and Tailscale turned a spare laptop into a real production host. Here's what actually mattered — and what I'd do differently.

#infrastructure#self-hosted
→

RAG in practice: what actually matters

Everyone's built a RAG demo. Almost nobody's built one that holds up on scanned PDFs, corporate jargon, and users who actually expect correct answers.

#ai#retrieval
→

Designing Aurion's payment flow on Solana

Notes on building a wallet-agnostic crypto payment microservice — the real problems were Jupiter routing, RPC failover, and staleness, not the happy path.

#solana#payments
→
Book a call → WhatsApp