The claim
Eighty percent of companies, eighty percent of the time, should run roughly the same architecture. The shape is so consistent across industries that you could draw it on a napkin in 2014 and again in 2026 and the napkin would still be useful. It is not glamorous, it does not win conference talks, and there is nothing to sell that is not already commoditised.
Engineers love to think their problem is special. Most aren’t. Most companies are running the same kinds of workloads with the same growth curves and the same compliance constraints, and the same boring stack solves it. The interesting question is not “what novel architecture should we build” but “are we one of the rare twenty percent who actually need something different, and if so, why?”. That question is much harder to answer honestly, which is why most teams skip it.
This lesson is the canonical default stack: the components, the costs, the reasons it is the default, and the symptoms that say you have outgrown it. Treat it as a reference card.
The default stack, named
Here is the shape, component by component, with what each one costs at small-to-medium scale. Costs are in EUR, in 2026, for a SaaS in the 10k to 100k MAU range.
- Cloudflare (or an equivalent CDN). Sits in front of everything. Terminates TLS, caches static assets, mitigates DDoS, gives you a WAF. Free tier covers most small projects, then about 20 EUR/month for Pro. Equivalents: Fastly, AWS CloudFront, Bunny CDN.
- Managed Postgres. The system of record. Holds users, accounts, orders, anything transactional. 50 to 300 EUR/month, depending on whether you self-host on a VM or pay AWS RDS / Supabase / Neon / Aiven.
- Redis (managed cache). The hot-path cache and rate limiter. 30 to 100 EUR/month for a small managed instance (Upstash, ElastiCache, Redis Cloud). Add it the day you can name a specific hot query, not before.
- Object storage (S3 or equivalent). User uploads, generated PDFs, video thumbnails, backups. 5 to 50 EUR/month for a typical SaaS, dominated by egress more than storage. Cloudflare R2 has no egress fees, which is a real money-saver.
- Two app servers behind a load balancer. The stateless web tier. Two so you can deploy without downtime and tolerate a single-machine failure. 100 to 400 EUR/month for the pair (Hetzner is the floor, AWS the ceiling). The load balancer is either cloud-managed (ALB, DO LB, Hetzner LB) or nginx on a tiny VM.
- A queue. Redis-based BullMQ, AWS SQS, or Postgres-based pgmq if you want one fewer piece of infrastructure. Basically free if you reuse Redis or Postgres.
- A worker fleet. One or two machines that pull jobs off the queue and run the slow stuff: emails, PDFs, retries, image processing. 50 to 200 EUR/month for a fleet that handles thousands of jobs per minute.
- Stripe for payments. The boring choice and the right one. 1.5% + 0.25 EUR per European transaction, more cross-border. Equivalents (Adyen, Braintree, Mollie) are also fine. Building your own payment integration is a project the size of your whole company, do not.
- A transactional email provider. SendGrid, Postmark, Resend, AWS SES, Mailgun. 0 to 50 EUR/month at low volume. Postmark has the best deliverability for transactional mail.
- Sentry for error tracking. Catches the exceptions your app throws so you do not grep logs at 2 a.m. Free tier covers most small teams, 30 to 100 EUR/month for a real production setup. Equivalents: Bugsnag, Rollbar, Honeybadger, GlitchTip.
- Datadog or Grafana Cloud for metrics + logs. 50 to 300 EUR/month. Datadog is excellent and expensive, Grafana Cloud is good and cheaper, self-hosted Prometheus + Loki + Tempo is free if you can spare the time.
- GitHub for code, GitHub Actions for CI. Free for public repos, free-ish for small private teams. CI runs tests, builds a container image, pushes it to a registry. Fifty lines of YAML, set it up once.
- Linear or Jira for issue tracking. Linear for small teams that like nice tools, Jira for larger teams with a process. The choice barely matters architecturally; it matters for the humans, so pick what they like.
Total: roughly 500 to 2000 EUR/month, all-in. That serves a typical SaaS from 10k to 1M users without a single architectural change. The application code grows, the database grows, occasionally you bump an instance up, but the shape stays the same. That is the entire point.
Why this is the default
Four reasons, all of them about humans.
It is well-known and well-trodden, so debugging is fast. Every component on that list has thousands of Stack Overflow answers, dozens of decent books, and an active community. When something breaks at 3 a.m., the first three Google results are likely to be people who broke it the same way and posted the fix. The clever distributed thing you might want to build instead has none of that. You will be the one writing the Stack Overflow answer, except you will not, because you will be debugging.
Every component has 3-5 viable alternatives, so vendor lock-in is manageable. Cloudflare can be swapped for Fastly. RDS for Aiven or Supabase. SES for Postmark. Datadog for Grafana Cloud. The interfaces are similar enough that a swap is a project measured in weeks, not years. Compare to a stack glued together from a single vendor’s proprietary primitives (DynamoDB, Lambda, Step Functions, EventBridge), which is operationally fine but architecturally a hostage situation. The default stack is portable on purpose.
The whole stack is operable by a 2-3 person team for a long time. No team needs a dedicated platform engineer to run this. The cloud handles the hard ops parts. One person can be on-call without dreading it. Operability is a property of the architecture, not just of the team.
The cost scales sub-linearly with revenue at this scale. A SaaS with 1,000 paying customers at 50 EUR/month is bringing in 50,000 EUR/month in revenue and spending maybe 1,500 EUR/month in infrastructure. That ratio gets better as you grow, until you hit one of the inflection points below.
When this stack starts hurting
The stack is the default, not the only option. Here are the symptoms that mean you have outgrown it. We covered the single-server starter’s failure modes in lesson 7; these are the ones that point at the default stack itself.
- The database becomes the bottleneck. Postgres CPU pegged at 80%+, IO wait climbing, lock contention in
pg_stat_activity, the buffer pool hit rate slumping. You have done the obvious things (added the missing indexes, killed the N+1 queries, added a read replica) and are still constrained. Time to think about partitioning, sharding, or a separate analytics database. - Single-region latency hurts a globally-distributed user base. Users in Sydney get 350 ms p95 because every request crosses three oceans to reach Frankfurt. CDN caching does not help because the requests are personalised. This is when you consider a multi-region deployment, which is a different and more expensive architecture.
- Compliance forces data residency. GDPR, India’s DPDP, China’s PIPL, or a sectoral rule (HIPAA, PCI Level 1) makes “all data lives in one Frankfurt RDS” no longer legal. You fork the database tier per region and keep the rest mostly the same.
- Real-time requirements emerge. Sub-100 ms p99 reads, presence, live collaborative editing, real-time bidding. The default stack with synchronous Postgres reads can hit 100 ms but not consistently at high concurrency. You start needing Redis Streams, event sourcing, or a real-time fabric like Centrifugo or Ably.
- Engineering team grows past ~20 people. The monolith is now a coordination nightmare. Three teams want to deploy at the same time. Tests take 25 minutes. The release calendar is a Tetris board. Time to carve the monolith into well-bounded services, on a measured schedule, not all at once.
If none of these are happening, the architecture is fine. Resist the urge to refactor toward a more impressive shape just because somebody wrote a blog post about it.
When NOT to start with this stack
The cases where you should pick something else from day one. They are real, they are rare.
- Hyperscale-from-day-one platforms. A global ad network, a real-time bidding system, a top-1000-by-traffic social product. Build something else, but be very honest about whether you are actually one of these.
- Regulated environments where the default stack does not pass audit. Medical record systems with top-tier HIPAA, banking core, defense, classified government. You may save months by starting on a compliant platform (AWS GovCloud, on-prem hardware, specific vendors with the right certifications).
- Embedded, IoT, or edge. If your “users” are 50,000 sensors reporting every 100 ms, your shape is MQTT + a time-series database + edge compute, not Cloudflare + Postgres.
- Latency-critical infrastructure. Trading systems, real-time bidding, sub-millisecond fraud scoring. Written in C++, on bare metal in a colo near the exchange, with specialised hardware. They cost a lot more.
- Very small projects. A personal blog needs less than this, not more. A side project with zero paying users can run on a single 5 EUR/month VM with SQLite and no CDN. Lesson 6 of this course is the right reference there.
If your project is none of these, you are in default-stack territory. Most projects are.
The “but my problem is special” trap
Engineers tend to over-engineer because the default looks boring. Boring is a feature, not a bug. Boring means battle-tested, well-documented, hireable-for, debuggable. The new shiny thing you read about last week is, in expectation, none of those, and the cost of being wrong about it is months of your life.
Real architects spend most of their time defending the default, not adding to it. They say “no” more often than they say “yes”. They ask “what specific problem does this solve that the default does not”, and they require a real answer. They insist that the proposer can name the rollback path. They look at the operational burden honestly: who is on-call for this new component, what is the playbook, what does it look like when it breaks at 3 a.m.? If the proposer cannot answer those, the new thing does not get added.
This is unglamorous work, and it is the work that keeps companies alive. The architects who add the most value tend to be the ones whose diagrams are the most boring.
The 2026 addendum: the AI layer
The 80% stack now usually includes an AI layer. If your SaaS exposes “ask the AI”, retrieval-augmented help, smart suggestions, or internal automation, the default expansion adds:
- An LLM gateway. A thin proxy in front of OpenAI, Anthropic, your hosted Llama, whatever. It does retries, fallbacks, cost accounting, prompt caching, rate limiting. Roll your own (a few hundred lines) or use LiteLLM, Helicone, Portkey, OpenRouter. 0 to 100 EUR/month plus the LLM bill itself.
- A vector database. Stores embeddings of your docs, your support history, your catalog. Postgres with pgvector handles most workloads up to a few million vectors and is the most boring choice; Pinecone, Weaviate, Qdrant, Chroma are the dedicated alternatives. Start with pgvector.
- An MCP server. Exposes your internal tools to whatever model your users or agents are using. A small Node or Python service, a few hundred lines, deployed alongside the workers. Most companies that take AI seriously expose at least a read-only MCP.
- An agent worker. A specialised worker fleet that runs longer LLM loops: a research agent, a support triager, an internal data analyst. Just like the normal worker fleet but with longer per-job timeouts and tighter cost limits.
These four are still optional, but they are increasingly default for SaaS that touches AI. They slot in next to the rest of the stack as an additional ring around the existing core. The Postgres still holds the truth, the Redis still caches the hot paths, the Stripe still takes the money.
For an interactive version of this expansion, see the Modern AI SaaS blueprint in the reference gallery.
The diagram
Here is the canonical shape, simplified to fit on a single screen. The reference gallery has the rich version with click-through node details; this one is the napkin.
flowchart LR
user[User] --> cdn[CDN / Cloudflare]
cdn --> lb[Load balancer]
lb --> app[App fleet x2]
app --> pg[(Postgres)]
app --> redis[(Redis cache)]
app --> s3[(Object storage)]
app --> queue[Queue]
queue --> workers[Workers]
workers --> pg
workers --> s3
app --> stripe[Stripe]
workers --> email[Email provider]
For an interactive version of the diagram, with click-through detail on every component, see the Standard SaaS blueprint in the reference gallery.
Closing
Architecture is mostly the boring default, applied with discipline. The interesting decisions are in what you don’t build, not what you do. A team that knows the default stack cold, knows when to deviate, and knows how to defend the default against the constant pressure to add to it, is a team that ships. Everything else is an architecture diagram nobody runs.
References
- Sam Newman, Building Microservices, 2nd edition, O’Reilly, 2021. The chapter on “When not to use microservices” is essentially this lesson, expanded to a book.
- Betsy Beyer, Chris Jones, Jennifer Petoff, Niall Richard Murphy, Site Reliability Engineering, O’Reilly, 2016. Free online at
https://sre.google/books/(retrieved 2026-05-08). The defining book on operating the kind of system this lesson describes. - Stripe Engineering, “Online migrations at scale”,
https://stripe.com/blog/online-migrations(retrieved 2026-05-08). The pattern reference for evolving a Postgres schema under load. - Pieter Levels, “How I built a startup with no employees”, Indie Hackers interview,
https://www.indiehackers.com/podcast/052-pieter-levels-of-nomad-list(retrieved 2026-05-08). The case for boring technology and staying small. - Dan McKinley, “Choose Boring Technology”,
https://boringtechnology.club/(retrieved 2026-05-08). The canonical essay on the principle this whole lesson rests on. - David Heinemeier Hansson, “The Majestic Monolith”,
https://m.signalvnoise.com/the-majestic-monolith/(retrieved 2026-05-08). The companion argument about why the small team should not over-architect.