The default move for a new SaaS is to reach for AWS, because AWS is the default. That's not a decision — it's the absence of one. When Prompterjack was young, it wore the default big-cloud outfit: containerised API, managed Postgres, a load balancer in front, the works. It ran fine. The problem was never that AWS couldn't do the job. The problem was a mismatch between the shape of the workload and the shape of the platform — and a solo developer pays for that mismatch in the two currencies they can least afford: idle cost and operational attention.
Start with the workload, not the vendor
Prompterjack's traffic profile, described honestly:
- Request-shaped. A user saves an agent design, exports code, hits Stripe checkout. Milliseconds-to-seconds of compute, then silence. No long-lived processes, no background daemons.
- Bursty and global. Traffic arrives in spikes from wherever a link got shared, then goes quiet. A fixed-size container is wrong in both directions: idle when quiet, queueing when spiked.
- Small state, relational. Designs, users, subscriptions — classic Postgres, gigabytes not terabytes.
- Solo-operated. Every hour spent on infrastructure is an hour not spent on the product. "It's possible to manage" is not the bar; "it doesn't need managing" is.
That shape has a name: it's an edge function workload. Once you say it out loud, the platform question mostly answers itself.
The matrix
Score your workload down these seven axes. Neither column "wins" — the point is that your workload lands clearly on one side, and if it doesn't, that ambiguity is itself the answer (see the last section).
| Axis | Cloudflare (Workers) | AWS |
|---|---|---|
| Compute model | V8 isolates. No cold starts worth the name, but also no long-lived processes, limited CPU time per request, no arbitrary binaries. | Anything: containers, VMs, Lambda, GPU boxes. If it runs on Linux, it runs here. |
| Idle cost | Zero. No traffic, no bill. The free tier absorbs an indie product's entire early life. | Rarely zero in practice — NAT gateways, load balancers, and "small" RDS instances bill while you sleep. |
| Pricing legibility | Per-request, flat, predictable. You can estimate a month's bill on a napkin. No egress fees is the quiet killer feature. | Powerful but adversarial. Cost is a skill you must acquire; egress pricing punishes success. |
| Latency profile | Code runs in every city your users are in, automatically. Global is the default, not an architecture project. | Fast in its region. Going global is a deliberate, expensive design decision. |
| Long-running / batch work | Wrong tool. Workers are request-scoped; a 40-minute training job or a persistent websocket daemon fights the platform. | The home game. Batch, queues-with-workers, spot fleets, step functions — this is what AWS is for. |
| Data gravity | Happiest with edge-native stores (KV, D1, R2) or HTTP-speaking databases. Classic TCP-to-Postgres needs a serverless driver. | If your data is already in a VPC — or compliance says it must be — the compute comes to the data, full stop. |
| Ops surface for one person | Deploy is wrangler deploy. There is no server to patch because there is no server. |
Everything is configurable, which means everything must be configured. IAM alone is a part-time job. |
What the shift actually looked like
The API was rewritten on Hono — an Express-shaped framework built for Workers — which made the move feel less like a migration and more like a change of shoes: routes, middleware and handlers map one-to-one. The interesting problem was Postgres. Workers don't hold classic TCP connections open, so the database moved to Neon, whose serverless driver speaks to Postgres over HTTP/WebSockets and whose scale-to-zero pricing matches the Workers philosophy: silence costs nothing. Stripe, being an HTTP API, did not care where it was called from. The Turborepo monorepo kept the React frontend and the Workers API in one place with shared types.
What was gained: a bill that tracks usage instead of existence, global latency for free, and a deploy pipeline with one command in it. What was given up — and this is real — is optionality: no long-running compute, CPU limits per request, and a platform you can't replicate locally with perfect fidelity. Those constraints are fine for this workload. They would be disqualifying for others.
Where I would still choose AWS without hesitation
This studio's own portfolio makes the case both ways. VolForecast — walk-forward model training, MLflow registries, scheduled retraining — is batch-shaped, long-running, and compute-hungry: an AWS workload to its bones. Anything with GPU inference, VPC-bound data, strict compliance regimes, or a genuine always-on daemon belongs on the big cloud. The matrix isn't a verdict; it's a sorting function.
The transferable lesson
Strip the logos off and the evaluation method is four questions:
- What shape is the compute? Request-scoped, batch, or resident? This eliminates more options than any benchmark.
- Can you predict the bill on a napkin? If you can't estimate next month's cost in five minutes, you'll discover it the hard way.
- What's the exit cost? Hono-on-Workers can move; a system woven through twelve proprietary services cannot. Price the lock-in before it prices you.
- Whose attention runs it? A platform is only "managed" relative to the size of your team. For a team of one, ops you don't do beats ops you could do.
And a closing honesty check: if your workload sits ambiguously between the columns, the boring answer is usually to split it — edge for the request path, big cloud for the batch path — rather than forcing one platform to be something it isn't. Clouds are tools, not teams to barrack for. I say that as someone with a whole website about barracking.