Architecture Tradeoff Explorer
Every comparison answers the same five questions — use when, avoid when, complexity, operational cost, failure modes — so the decision is about your constraints, not the fashion of the year.
Monolith vs MicroservicesREST vs GraphQLREST vs gRPCSynchronous call vs Asynchronous (queue)Relational (SQL) vs NoSQL (document / key-value)Queue (point-to-point) vs Pub/Sub (topic)Event-driven vs Request/responseCache (Redis / CDN / in-process) vs DatabaseCQRS vs CRUDEvent sourcing vs State storage
One deployable with local calls and one transaction, or many deployables with network calls and none. The monolith is the default; microservices are the answer to a measured organisational or scaling problem, and to nothing else.
| Monolith Monolithic Architecture | Microservices Microservices | |
|---|---|---|
| Use when | One or two teams, one product, a domain still being discovered. Every write can use one local transaction and every call is a function call. | Several teams that block each other on deploys, parts that scale an order of magnitude apart, and data that each team can own outright — with tracing, per-service pipelines and on-call already in place. |
| Avoid when | Eight teams queue behind one release train and one module needs 20× the capacity of the rest; the process has become the bottleneck for the organisation, not the CPU. | The team is small, the domain boundaries are guesses, or the services would share tables. You would pay for distributed systems without buying autonomy. |
| Complexity | Low: one codebase, one process, one database. The risk is internal entropy — modules reaching into each other until nothing can be extracted. | High: N contracts, service discovery, a gateway, sagas or an outbox for cross-service writes, versioning, partial failures on every call. |
| Operational cost | One pipeline, one dashboard, one on-call rota; scaling is copies behind a load balancer until the database is the ceiling. | N pipelines and dashboards, distributed tracing, a platform team; a slow or failing dependency is an incident category of its own. |
| Failure modes | The process is the failure domain: an OOM in reporting takes checkout down. Deploys are all-or-nothing, and a shared database lock stalls everyone. | Retry storms (3 × 3 × 3 = 27×), cascading timeouts through call chains, an order shipped when payment failed, a distributed monolith when services share a database. |
| Data flow | Request → controller → module functions → one database, inside one transaction | Request → gateway → service → its database; consequences via events or sagas across services |
| Consistency | ACID across the whole domain for free | Local to each service; cross-service consistency is eventual and must be designed (outbox, saga, compensation) |
| Observability | A stack trace and one log stream explain most incidents | A trace id, propagated across every hop, is the only way to answer "where did the 800 ms go" |
| Team shape | One team or several sharing one codebase with module ownership | One team per service, each owning code, data, deploys and on-call |