Every founder has heard the same advice: "Don't over-engineer." And every founder has also heard: "Build for scale from day one." These sound contradictory. They're not. Here's the founder's playbook for using cloud infrastructure to get from zero to a million users without melting your AWS bill or your team.
Across modern cloud engagements, startups make two classic mistakes. The first is building for a billion users before they have ten — burning runway on complexity they don't need. The second is building for ten users and then panicking when they get a million — scrambling to replatform under load. Both failure modes are avoidable with a small number of architectural choices up front.
Stage 1: Zero to 1,000 users — do the simplest possible thing
At this stage, every minute you spend on infrastructure is a minute not spent on product-market fit. The correct default stack is boring and embarrassingly simple:
- One monolithic web app, deployed on a PaaS like Vercel, Railway, or Render.
- A managed Postgres database (Supabase, Neon, or RDS).
- Object storage for files (S3, R2, or equivalent).
- A cron runner for any background jobs.
That's the entire architecture. No Kubernetes. No microservices. No multi-region setup. Teams that try to skip ahead here regret it every time.
Stage 2: 1,000 to 100,000 users — add seams, not services
Somewhere between ten thousand and a hundred thousand users, the simple stack will start showing its first cracks. The right response is usually not to "split the monolith." It's to add seams inside the monolith that make future splits easy.
Concretely: extract the slowest endpoints to background jobs. Move expensive reads behind a Redis cache. Add an async event bus (even if it's just Postgres LISTEN/NOTIFY) for cross-module communication. And invest in observability — real logging, tracing, and metrics — before you think you need it.
"Every major incident in year one traces back to "we didn't have visibility into what was happening." Once you fix that, the rest of scaling gets dramatically easier."
Stage 3: 100,000 to 1,000,000 users — now you can split
This is the stage where microservices start paying for themselves — but only if you split along the right lines. The seams you added in stage 2 should now guide the splits. If your payments module has been well-bounded behind an internal interface, extracting it into a service is a weekend project. If it's woven into your user-model throughout, it's a six-month migration.
A few patterns that consistently pay off at this stage:
- Read replicas for your main database, fronted by a read-only connection pool.
- A dedicated analytics pipeline (event bus + warehouse + BI) to keep OLAP queries off your OLTP database.
- A CDN with aggressive caching for anything public-facing. This alone often gets you another 10x in effective capacity.
- Rate limiting at the edge, so bad actors can't DDoS your application servers.
The architectural decisions to defer as long as possible
Here are decisions founders often make too early — almost always to their detriment:
Multi-region
Unless you have users on multiple continents with strict latency requirements, single-region is fine up to a million users. Multi-region introduces correctness, cost, and complexity that will dominate your engineering calendar for months.
Kubernetes
K8s is great when you have multiple services and a dedicated platform team. Before that, it's a tax on your velocity. Stay on PaaS as long as you possibly can.
Event sourcing
Event sourcing is powerful and right for specific domains (finance, audit-heavy systems). For most startups it's a framework for writing 10x the code to solve problems you don't have yet.
The cost of getting it right: less than you think
Founders often overestimate how expensive correct cloud architecture is. A well-architected stack for a million-user SaaS usually runs somewhere between $2K and $8K/month at that scale — far less than a single senior engineer. The mistake isn't spending on cloud; it's spending in the wrong places.