🧭 15 · DECISION FLOWCHARTS
Which API Style? Choose based on audience , data shape , and performance needs
Is the API client-facing
or internal?
Internal
gRPC
Protobuf · HTTP/2
10x faster · type-safe
Client-facing
Is over/under-fetching
a concern?
Yes
GraphQL
Client picks fields
Single endpoint
No
REST
HTTP verbs · cacheable
Default for public APIs
Need streaming?
Bidirectional or server-push?
Bidir
WebSocket
Server→Client
SSE
Legacy/simple?
Long Polling
Which Database? Choose based on access pattern , consistency needs , and scale
Need ACID + complex joins?
Yes
SQL (Postgres)
Strong consistency · JOINs
No
High write throughput?
Yes
Cassandra / ScyllaDB
Wide-column · LSM-tree
Flexible schema / JSON?
Yes
MongoDB
Document · single-doc ACID
Sub-ms key lookup?
Yes
Redis / DynamoDB
Key-Value · O(1)
Relationships / Search / Global?
Neo4j
Graph
Elasticsearch
Search
Spanner
Global ACID
Queue vs Stream vs Pub/Sub? Choose based on consumption model and retention needs
How many consumers per msg?
One
Queue
RabbitMQ · SQS
msg deleted after ACK
Many
Need replay / retention?
Yes
Event Stream
Kafka · Kinesis
durable log · rewind
No
Pub/Sub
SNS · Google Pub/Sub
broadcast · fire-and-forget
Fan-out + per-svc buffering?
SNS → SQS → Lambda
Technology Model Ordering Retention Best For
SQS Queue (1 consumer per msg) FIFO optional 14 days max Task distribution, decoupling services
Kafka Log (N consumers, replay) Partition-ordered Configurable (days→forever) Event sourcing, streaming, high throughput
RabbitMQ Queue + Exchange routing Per-queue FIFO Until consumed Complex routing, priority queues, RPC
Redis Pub/Sub Pub/Sub (fire & forget) None Zero (no persistence) Ephemeral events, typing indicators, cache invalidation
SNS + SQS Fan-out (1 msg → N queues) Per-subscriber queue Per SQS settings Event notifications to multiple services
NATS Pub/Sub + JetStream Stream-ordered JetStream: configurable Lightweight microservice messaging, IoT
Decision shortcut: Need replay? → Kafka . Need exactly-once task processing? → SQS . Need complex routing (topic/fanout/headers)? → RabbitMQ . Need fire-and-forget speed? → Redis Pub/Sub . Need fan-out to multiple services? → SNS+SQS .
Which Caching Strategy? Choose based on read/write ratio and consistency needs
Read-heavy or write-heavy?
Read-heavy
App controls cache logic?
Yes
Cache-Aside
most common
No
Read-Through
cache auto-fetches
Write-heavy
Need strong consistency?
Yes
Write-Through
sync to DB
No
Write-Back
async flush · fast
⚠ data loss risk
Write-rarely, read-later?
Write-Around
write DB directly
Which Real-time Tech? Choose based on direction , latency , and who talks to whom
Server-to-server or client?
Server→Server
Webhook
Client
Direction of data flow?
Bidirectional
WebSocket
chat · stocks · gaming
Server→Client
SSE
AI streaming · logs
Peer-to-peer media?
WebRTC
video · audio · screen share
Simple / legacy? → Long Polling
Technology Direction Latency Connection Best For
WebSocket Bidirectional <50ms Persistent, stateful Chat, gaming, collaborative editing
SSE Server → Client only <100ms Persistent, HTTP-based Live feeds, notifications, dashboards
gRPC Streaming Both (4 modes) <10ms HTTP/2 multiplexed Internal microservice streaming, telemetry
Long Polling Client pulls 100-1000ms Repeated HTTP requests Simple fallback, legacy browser support
WebRTC Peer-to-peer <100ms P2P (STUN/TURN) Video/audio calls, screen sharing
MQTT Pub/Sub (lightweight) <50ms Persistent TCP IoT devices, low-bandwidth networks
Decision shortcut: Browser + bidirectional? → WebSocket . Browser + server-push only? → SSE (simpler, auto-reconnect). Internal services? → gRPC streaming . Video/audio? → WebRTC . IoT/constrained? → MQTT . Legacy/simple? → Long Polling .
How to Scale? Choose based on bottleneck type — reads, writes, or both
What's the bottleneck?
Reads
Read Replicas
Cache (Redis)
CDN
Writes
Sharding
Partitioning
Write-Behind Cache
Both
Can a bigger machine handle it?
Yes
Scale Up (vertical)
simple, no code changes
No
Scale Out (horizontal)
LB + sharding + stateless
Start vertical → go horizontal when you hit the ceiling
More Decision Flowcharts Quick decision trees for common architecture choices
Sync vs Async Communication
Need immediate response?
Yes
Sync
HTTP / gRPC
direct call + wait
No
Need retry / replay?
Yes
Event Stream
Kafka · durable log
No
Multiple consumers?
Yes
Pub/Sub
SNS · fan-out
No
Task Queue
SQS · RabbitMQ
Rule: if caller can't wait → async. If need replay → Kafka.
Monolith vs Microservices
Team size > 10 engineers?
No
Monolith
simple deploy
single codebase
Yes
Need independent deploy
per service?
No
Modular Mono
bounded contexts
single deploy unit
Yes
Need different tech stacks?
Yes
Microservices
polyglot · independent
No
SOA / Mini-svc
same stack, split deploys
Rule: start monolith → modular mono → split to services when team/scale demands
SQL vs NoSQL
Need ACID + complex JOINs?
Yes
SQL
Postgres · MySQL
strong consistency
No
Write-heavy (>100K/sec)?
Yes
Wide-Column
Cassandra · ScyllaDB
No
Flexible schema / JSON docs?
Yes
Document
MongoDB · DynamoDB
No
Key-Value
Redis · DynamoDB
sub-ms lookups
Rule: relationships → SQL. Scale writes → Cassandra. Flexible → Mongo.
Interview meta-tip: When asked "how would you design X?" — start by identifying which of these decisions apply. Most systems need: API style (REST/gRPC) + database (SQL/NoSQL) + communication (sync/async) + caching strategy . Name the tradeoff explicitly: "I'm choosing X over Y because of Z constraint."