I built a tool for drawing AWS architecture diagrams for a living. I never properly diagrammed my own product's architecture until last week.

It sounds ironic, but it isn't really. When you're building solo, the architecture just lives in your head. You don't need a diagram to remember decisions you made three months ago. Then something breaks at 11pm, and you're trying to reconstruct why a request is timing out somewhere between three services you half-remember configuring.

So I sat down and actually drew it. Here's what DesignBeaver's production setup looks like, and more usefully, what I'd do differently if I were starting today.

The Setup

DesignBeaver.app high level diagram

Compute runs on ECS/Fargate. Database is RDS Postgres. Deploys go through a CI/CD pipeline. On paper, that's a completely unremarkable stack. That's kind of the point.

The Decision Worth Talking About: Fargate Over EC2 or Lambda

When I was picking compute, I had three real options. EC2 was cheapest with the most control, but also the most ops burden. Lambda was cheapest at low traffic, but awkward for a stateful app with WebSocket-ish real-time diagram editing. Fargate cost more than EC2 at steady load, but needed almost no server management.

I picked Fargate. The honest reason wasn't a deep technical argument. I was solo, shipping fast, and every hour spent patching an EC2 instance or debugging an AMI was an hour not spent on the actual product. Fargate cost me some money and some control I didn't have deep expertise in optimizing anyway. In exchange, I got to stop thinking about the underlying host at all.

Nobody puts this tradeoff in the "AWS compute comparison" tutorials. The right answer isn't the cheapest option or the most scalable one. It's whichever one matches your actual constraint, and for a solo builder that constraint is almost always attention, not dollars or some theoretical scale ceiling.

I'd make the same call again, though I'd make it more deliberately this time. At the time, it was closer to "Fargate is the default everyone recommends" than "I evaluated my constraint and Fargate won." Same outcome, weaker reasoning behind it.

What I'd Change: Observability

If I had more time right now, the first thing I'd fix isn't compute or database. It's that I have almost no real visibility into what's actually happening in production beyond basic uptime and error logs.

When something goes wrong today, my process is: check CloudWatch logs, grep for the error, guess at the request path that caused it. That works fine when the system is small and I've personally touched every part of it. It stops working the moment either the codebase or the traffic outgrows what fits in my head.

The real gap is structured tracing across the request path. Without it, I can't answer "where did this specific slow request actually spend its time" without manually reconstructing the whole thing by hand. It's on my list now, not because some tutorial told me to add observability, but because I've personally felt the cost of not having it.

The One Thing I'd Prioritize Differently

If you're building solo and picking your first production stack, don't spend your limited time deliberating endlessly between EC2 vs Fargate vs Lambda. Pick whichever removes the most day-to-day ops burden and move on. That decision rarely bites you early.

Observability will. It's the thing solo builders skip because it never feels urgent, right up until the moment it's the only thing that matters. If I were starting DesignBeaver today, I'd trade a week of feature work for basic tracing before I needed it, not after.

Keep Reading