A 36-minute tour of system-level shapes — monolith to microservices, the BFF, API gateways, event-driven, serverless, and how to migrate safely. We'll be honest about where the simpler option quietly wins.
Inside one process, a bad boundary is a slow refactor. Across a network, the same bad boundary becomes a retry storm, a failed deploy, and a 2 a.m. page. An architecture style is just where you draw the deployment and integration lines — and what those lines cost when they cross the wire.
Same four concerns. On the left, calls can't fail; on the right, every line is a thing that can break.
Simple ops, one deploy, easy local dev, transactions are free. Most products should start here.
Independent scaling and deploys, team autonomy, fault isolation — if the boundaries are real.
Distributed adds network failure, partial failure, data consistency, and observability cost to everything.
Don't pay the distributed tax until coupling pain — not résumé envy — forces it.
These aren't three tribes — they're three points on one line, trading deployment simplicity for independence. The honest truth of 2026: microservices are over-adopted. Most teams reach for them years before the pain that justifies them, and pay the tax the whole time.
The middle option is the one most teams skip — and the one most teams actually need.
Cut along bounded contexts (DDD) — language and ownership that change together. A network boundary that follows a real seam is cheap; one that splits a transaction is misery.
A web grid, a mobile list, and a partner integration want very different shapes of the same data. A BFF is a thin backend owned by each client team that talks to the downstream services and returns exactly what that client needs — no over-fetching, no twelve round-trips.
Each client owns a BFF; the BFFs share the same downstream services.
Like a personal shopper per customer — same warehouse, but each comes back with a bag packed for one person. The cousin idea on the UI side is micro-frontends; powerful, equally over-adopted — one team rarely needs them.
Clients shouldn't know your service map. An API gatewayis the single entry point that handles the cross-cutting chores — routing, auth, rate limits, TLS — so each service doesn't. Behind it, services talk to each other two ways, and the choice shapes how failure spreads.
Auth and routing happen once, at the edge — services stay focused on their job.
Pick on operating model: self-host for control, managed for less ops, full lifecycle for big API programs.
Pro — open-source, plugin-rich, runs anywhere (self-host or cloud).
Con — you run and scale it yourself.
Choose when you want portability and deep customization.
Pro — fully managed, native Lambda / IAM integration, scale-to-zero.
Con — AWS-locked; per-request cost adds up at high volume.
Choosewhen you're already serverless on AWS.
Pro — full API lifecycle: dev portal, monetization, analytics.
Con — heavyweight and pricey; overkill for internal traffic.
Choose when APIs are a product sold to external developers.
Pick on the call's shape: who consumes it, how tight the latency budget, and whether the caller can wait.
Pro — universal, cache-friendly, debuggable with curl.
Con — chatty; no schema by default.
Choose for public APIs and broad reach.
Pro — fast binary, strict schema, streaming, codegen.
Con — not browser-native; harder to eyeball.
Choose for internal, high-throughput service mesh.
Pro — client picks fields; one round-trip for varied UIs.
Con — server complexity; caching and N+1 are real work.
Choose for rich, client-driven frontends / BFFs.
Pro — decouples availability; absorbs spikes.
Con — eventual consistency; harder to trace.
Choosewhen the caller doesn't need an answer now.
In an event-driven style, a service announces a fact — OrderPlaced— and walks away. Anyone interested reacts. Producers don't know consumers, so you add new reactions without touching the source. That decoupling is the whole appeal — and the eventual consistency is the whole cost.
Pub/sub: Orders publishes once; three consumers react. Adding a fourth touches nobody upstream.
CQRS: writes append events; reads are served from projections built off that log.
Serverlesslets you ship a function, not a fleet: the platform runs it on demand and scales it to zero when idle. And when you finally do modernize a monolith, you don't rewrite it in one terrifying leap — you strangle it, one route at a time.
Spiky or low traffic, glue/cron jobs, event handlers, webhooks, lightweight APIs at the edge.
Steady high traffic (cheaper on always-on compute), long jobs, ultra-low-latency, heavy stateful workloads.
Cold starts, timeouts, and lock-in. Keep functions small and the business logic provider-agnostic.
Pro — deepest ecosystem; integrates with everything in AWS.
Con — cold starts on big runtimes; AWS lock-in.
Choose when you live in AWS and need rich event sources.
Pro — clean DX, tight Firebase / GCP data integration.
Con — smaller ecosystem than Lambda.
Choose when your data and stack already sit on GCP.
Pro — runs at the edge with near-zero cold start (V8 isolates).
Con — constrained runtime; not full Node by default.
Choose for global low-latency edge logic and lightweight APIs.
The facade shifts routes from legacy to new, one slice at a time — no big-bang rewrite.
There is no "best" architecture — only the cheapest one that meets today's real constraints. The recurring mistake is buying distributed complexity on credit and paying interest forever.
Five quick questions on monoliths, BFFs, gateways, events, and migration — instant feedback, no sign-in.
Navigate with ← → or scroll · back to library