System Design Concepts

No fluff — visual, concise, interview-ready

🧭 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
TechnologyModelOrderingRetentionBest For
SQSQueue (1 consumer per msg)FIFO optional14 days maxTask distribution, decoupling services
KafkaLog (N consumers, replay)Partition-orderedConfigurable (days→forever)Event sourcing, streaming, high throughput
RabbitMQQueue + Exchange routingPer-queue FIFOUntil consumedComplex routing, priority queues, RPC
Redis Pub/SubPub/Sub (fire & forget)NoneZero (no persistence)Ephemeral events, typing indicators, cache invalidation
SNS + SQSFan-out (1 msg → N queues)Per-subscriber queuePer SQS settingsEvent notifications to multiple services
NATSPub/Sub + JetStreamStream-orderedJetStream: configurableLightweight 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
TechnologyDirectionLatencyConnectionBest For
WebSocketBidirectional<50msPersistent, statefulChat, gaming, collaborative editing
SSEServer → Client only<100msPersistent, HTTP-basedLive feeds, notifications, dashboards
gRPC StreamingBoth (4 modes)<10msHTTP/2 multiplexedInternal microservice streaming, telemetry
Long PollingClient pulls100-1000msRepeated HTTP requestsSimple fallback, legacy browser support
WebRTCPeer-to-peer<100msP2P (STUN/TURN)Video/audio calls, screen sharing
MQTTPub/Sub (lightweight)<50msPersistent TCPIoT 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."