Cloud
A pragmatic AWS setup for solo devs and small teams
AWS punishes ambition. The “right” enterprise setup — multi-account with Control Tower, EKS, dedicated networking, a platform team — is exactly what a solo dev or three-person startup doesn’t need. Here’s the setup I recommend instead, biased toward what you can run alone at 2am without paging anyone.
The minimal stack that gets you to production
For a small team shipping a web app: one AWS account, one VPC, ECS Fargate for the app, RDS Postgres for the database, S3 for static assets, CloudFront in front of it, and Route 53 for DNS. That’s it. No Kubernetes, no service mesh, no separate “data plane.” Total monthly cost for a small production app is usually $80–$200 — reasonable for the reliability you get.
Skip the temptation of “production-grade” patterns until you have production-grade problems. You don’t need three environments; you need two (production and one shared staging, or just production with feature flags). You don’t need blue/green; you need a rolling deploy that takes three minutes and a rollback that takes two.
Cost guardrails before they hurt
AWS will quietly run up four-figure bills if you’re not paying attention. Three guardrails that take an hour to set up and save you weeks of stress:
- A billing alarm that emails you at $50, $200, $500.
- A budget action that disables resources at a hard ceiling.
- An S3 lifecycle policy that moves old logs to Glacier or deletes them.
The lifecycle policy alone has saved teams I’ve consulted for thousands of dollars in storage they forgot they had. A note on NAT Gateways: they’re $32/month each, plus per-GB data charges. For a small app, that’s the single biggest “I didn’t know it cost that much” line item. If you can avoid them (use VPC endpoints for S3/DynamoDB, run public-subnet workers for non-sensitive jobs), you’ll save real money.
Upgrade paths to plan for
When this stack starts to creak — usually around 100k requests/day or 50GB of database — you’ll have three real upgrades: read replicas on RDS for read-heavy workloads, Redis via ElastiCache for cache and queues, and either ECS Service Connect or App Mesh if you have more than three services that talk to each other. Each is a one-day migration, not a re-platform. The minimal stack was designed to hold you up to the moment any of those becomes obvious.
The lesson I keep relearning: you don’t need the architecture you’ll have in three years. You need the architecture you can debug at 2am with a coffee. Start small, observe what hurts, upgrade exactly that.
If you’d rather hand off the AWS setup to someone who’s done it twenty times, that’s a valid choice — most of my smaller clients prefer it. For more on the kind of perf problems this stack handles well, see cutting P95 latency on Next.js + Postgres.
READ NEXT
Cutting P95 latency by 60% on a Next.js + Postgres stack
A profiling playbook: which spans actually matter, where the wins hide, and how to measure without lying to yourself.
Designing APIs that survive a redesign of the frontend
Resource shapes, pagination, idempotency, and the contract tests that catch silent breakage early.
Building admin dashboards that ops teams actually use
Information density, defaults that respect the workflow, and the underrated power of a good empty state.