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
The caller waits, or the caller hands the work to a broker and moves on. Synchronous is simpler and consistent; asynchronous decouples rate and availability at the price of eventual state, duplicates and an invisible backlog.
| Synchronous call Request/Response vs Event-Driven | Asynchronous (queue) Message Queues | |
|---|---|---|
| Use when | The caller needs the result to respond, the dependency chain is short, and strong consistency is required — a price, an authorisation, a stock check. | The work can happen later, is retryable (idempotent), and the producer's rate or availability must not depend on the consumer — emails, thumbnails, exports, fan-out. |
| Avoid when | The dependency is external and slow at the tail and the caller could accept "pending"; every waiting request holds a thread. | The handler is not idempotent, the caller needs read-your-writes, or nobody will watch queue depth and oldest-message age. |
| Complexity | Low: a call with a timeout; add retry budget and a breaker when the dependency is external. | Medium: a broker, ack/visibility timeout, retry with backoff, dead-letter queue, idempotent consumers, a status path for the user. |
| Operational cost | Latency and availability compose: the caller inherits the callee's p99 and its outages. | A broker to run and monitor; consumer scaling by depth; the failure mode moves from "slow response" to "silent backlog". |
| Failure modes | Cascading timeouts, exhausted thread pools, retry amplification through the chain. | Backlog growing for hours unnoticed, stale state shown to users, lost consequence when the event was published after the commit without an outbox, duplicates on redelivery. |
| Data flow | A → B → A, in the request | A → broker → B, later; result surfaces via a status entity, callback or event |
| Consistency | Strong: the caller sees the effect on return | Eventual: the effect lands after the response; the entity carries a pending state |
| Observability | Latency histograms and error rates per call | Queue depth, oldest-message age, consumer lag, DLQ size |