Choosing an architecture — a decision framework
No stack is universally best. Match the workload, the team, and the deployment target. Start boring, scale up complexity only when measurements force you.
Nobody picks the 'best' backend — everyone picks a trade-off. The real skill is making the trade-off EXPLICIT: what am I optimizing for, and what am I sacrificing?
Five dimensions that drive good choices: (1) workload nature (CPU vs I/O, real-time vs batch), (2) team skills + size, (3) ecosystem needs (ML libs, admin UI, payment SDKs), (4) deployment constraints (existing cloud, latency SLA), (5) time-to-market pressure.
Heuristic that's right 80% of the time: start with a boring, batteries-included monolith in the language your team knows best. Django for Python teams, Rails for Ruby, Laravel for PHP, Phoenix for real-time + Elixir. Ship fast. Reach for microservices / async / edge only when measurements force you to.
Common anti-patterns: (1) 'we'll need microservices at our scale' (you won't, not at 10k users). (2) 'Tech X serves 1M req/s on benchmarks' (your bottleneck is your DB). (3) 'copying FAANG architecture' (you are not Google; their problems are not yours). (4) 'let's rewrite in the hot new thing' (the existing code works; the rewrite usually doesn't).
Write down WHY you chose the stack, because future-you — or your replacement — will wonder when a bug hits at 3am. A one-page README explaining the constraints + trade-offs + rejected alternatives is worth hundreds of hours of later archaeology.
Grounded on https://martinfowler.com/bliki/MonolithFirst.html