XenneX/LLC
All posts
By Buddy Delaune

Not Everything Runs on AWS. Here's What Doesn't.

AWS is my default, but my staging servers run on a Mac mini and Game Night's API runs on Cloudflare Workers. Here's what lives off AWS and why it's there.

#cloud infrastructure#AWS#cloudflare#self-hosting#engineering decisions
A small silver mini computer with a green status light on a wooden windowsill at dusk, beside a lamp, a potted plant, and a mug, with an orange-lit cloud outside

Back in July I wrote about why I almost always go with AWS. I still do. When a client project needs a database, storage, queues, and scheduled jobs that all work together, and someone else will maintain it after me, AWS is the answer nine times out of ten.

But "almost always" was doing real work in that title. A good chunk of what I run every day doesn't touch AWS at all. Here's what lives somewhere else, and why.

Staging Runs on a Mac Mini

My staging environments run on a Mac mini, inside a self-hosted platform called Coolify. That covers the AI Recaps API, both AI Recaps web apps, and Game Night. I push, Coolify builds the container, and a few minutes later I can test it.

None of it is on the public internet. Staging is only reachable over my private Tailscale network, so it's there for me and my devices and nobody else.

Staging needs three things: to be cheap, to be always on, and to be private. It doesn't need to scale, and it doesn't need five nines of uptime. If it goes down for an afternoon, nobody's users notice. Paying cloud prices for a handful of always-on containers that only I ever load would be paying for guarantees I don't need.

What I gave up: someone else being on call. When it breaks, it's mine to fix. Back in April, a Tailscale update broke DNS inside the Coolify machine, and every deploy started failing because it couldn't pull images or reach GitHub. Nothing in the app was wrong. It took pointing the machine at public DNS servers to get it working again. On a managed platform, that's never my problem. Here, it was my whole afternoon.

Game Night's API Runs on Cloudflare Workers

The first Game Night API was a LoopBack 3 app backed by MySQL. It worked, but it was an old framework on a full server for an API that mostly hands out question packs.

In May I rewrote it as a small Hono app on Cloudflare Workers, with the data in D1, Cloudflare's SQLite database. Before switching the app over, I ran the same test suite against the old API and the new one until they matched, then pointed the Android app at v2.

Why not AWS? I could have built it with Lambda and a managed database, and it would have worked. But this API is small, mostly reads, and busiest on Friday and Saturday nights. Workers runs it close to the user, the database lives on the same platform, and there's no server to patch. For a party game, that's the whole job.

What I gave up: the comfort of a normal server. Workers isn't Node, D1 isn't MySQL, and a few things I used to take for granted had to change. Some card data came over wrong in the move, and I spent a few days backfilling values from the old database. The rewrite cost a few weeks. I'd make the same call again.

Static Sites Go Where Static Sites Belong

The July post said static marketing sites often do better on platforms built for them. I follow my own advice here. Redinfinite is on Cloudflare Pages, the Game Night site is on Netlify, and this site is on Vercel. Push to main, the site rebuilds, done.

Could they all live in an S3 bucket behind CloudFront? Sure. But I'd be wiring up builds, previews, and cache invalidation myself to get what these platforms give me for free.

How I Decide

The rule I've landed on is simple:

  1. If someone else will inherit it, it goes on AWS. Client work, anything a future hire has to understand, anything with a lot of services that need to talk to each other.
  2. If it's small, separate, and mine, it goes wherever fits the job best. That's how a party game API ends up on Workers and my staging ends up on a Mac mini.
  3. If it only matters to me, I can host it myself. Staging, internal tools, things where downtime costs me an afternoon and nobody else anything.

AWS is still the default. A default is just the answer you give when nothing about the project argues for a different one. Some projects do.

If you're trying to figure out where your own stack should live, I can help you sort it out.

Working on something like this? See cloud and backend work or what XenneX has built.

Keep reading