A few weeks ago I deleted two years of work.
Thirty-four automations that run every day — for me and for my clients. WhatsApp AI bots, lead capture from Facebook and web forms, PDF report generation, calendar booking, CRM sync, notifications. All of them built the same way: box after box, dragged and dropped onto a visual canvas.
I deleted the lot and rewrote them in code.
This isn't a "no-code is bad" post. The visual platform I used (n8n) is genuinely excellent and open-source, and it let me ship fast for years. But as the system grew, I started fighting the tooling instead of building. So I want to walk through why code-first won for my use case, the numbers that came out of it, and — importantly — the parts that did not improve, because I have no interest in hype.
What "code-first" actually changed
Here's the before/after, minus the buzzwords.
Maintenance. Before, every change meant opening a browser, hunting for the right node inside a diagram, and dragging. Now every change is a line of code and a git commit. Full history, real diffs, code review, and instant rollback when something breaks.
Building. Before, each new automation was assembled from scratch on the canvas. Now I compose typed, reusable modules. Faster, and consistent across the whole system.
Control. The logic is mine, written explicitly. No magic behind a box, no surprises.
No lock-in. It's standard code in an open format. It runs anywhere; it isn't married to any one platform's JSON schema.
I built on DBOS — a framework that runs workflows written as ordinary TypeScript, backed by Postgres, with durable execution built in. More on that below.
The numbers
The headline that still makes me smile:
Memory: from ~1.4GB down to ~150MB. Roughly 10×.
Same 34 automations, same work, a tenth of the footprint. At idle the new stack sits around 48MB. A smaller, cheaper server now runs the same load with plenty of room to grow.
A couple more measured figures:
| Metric | Result |
|---|---|
| Throughput | ~1,167 workflows/second |
| Per-workflow overhead | ~30ms |
| Idle memory | ~48MB |
| Memory vs. old stack | ~150MB vs ~1.4GB (~10×) |
Where did the memory go before? To scale under load I had to add worker processes and a queue layer — each one eating more RAM. Now the base is so light that most of the time there's simply nothing to talk about.
The honest part (because I hate hype)
The bots themselves are not faster to respond. Here's why: when a bot talks to a large language model, the LLM sets the pace, not the infrastructure around it. The model's "thinking" takes what it takes, and no runtime swap changes that.
So what did I actually gain? A server that breathes, far higher concurrency, and lower infrastructure cost. Stability and efficiency — not the latency of a single reply. If someone tells you a runtime swap made their AI bot "instant," be skeptical.
How one person did all this
Translating 34 live automations to code, keeping behavior identical, testing each one, and shipping to production without a single client noticing — that is not a one-person job. Historically it's a team, over weeks.
I did it solo, working with Claude Code.
In practice it was a dialogue with a tool that reads code like a senior engineer: it helped me understand each existing automation, rewrite it in TypeScript, catch bugs before production, and verify each flow against the original. I direct, decide, and approve; it does the heavy lifting, fast.
And the migration itself was invisible to the outside world. A Caddy reverse proxy routes all the inbound traffic — WhatsApp, webhooks, forms — so every sender kept hitting the same endpoints. I swapped the engine mid-flight; nobody felt a thing.
The takeaway
The real story here isn't DBOS versus n8n. It's that the ceiling moved.
For years we all learned to work inside limits: "too complex to hand-write," "needs a team," "not worth the weeks." A lot of those limits just quietly disappeared, and our habits haven't caught up yet.
So the question I keep asking myself now isn't "how do I do what I already do, a bit faster?" It's "what would I build if the technical barrier weren't there?" Half of my someday-list turns out to be within reach today.
Next article: a technical deep-dive into the one feature that made this migration worth it — exactly-once durable execution — with real code.
Have you moved something from no-code to code-first? What pushed you over the edge? I'd genuinely like to hear it.
Top comments (0)