System Design

System Design Interview Patterns

Reusable patterns for fan-out, sharding, queues, idempotency, sagas, circuit breakers — and when to apply each.

Interview tip For any scenario, name 2–3 patterns aloud: "fan-out on write for notifications, idempotent consumers, circuit breaker on payment API."

① Pattern map — quick reference

PatternProblem it solvesWatch out for
Fan-out on writePrecompute feeds/notifications at write timeCelebrity problem — too many followers
Fan-out on readMerge at read time — simpler writesSlow reads for users following many accounts
ShardingSplit data across nodes by keyCross-shard queries, rebalancing pain
Consistent hashingMinimal key redistribution when nodes changeHot spots if key distribution skewed
Message queueDecouple producers/consumers, absorb spikesOrdering, duplicate delivery, poison messages
IdempotencySafe retries without duplicate side effectsKey storage TTL, scope of "same" operation
SagaMulti-step workflow without 2PC locksCompensating transactions complexity
Circuit breakerStop calling failing dependencyHalf-open state tuning, cascading if misconfigured

② Fan-out on write vs read

Fan-out on write (push model): When user A posts, push post ID into every follower's feed cache (Redis sorted set). Read = O(1) fetch prebuilt feed. Write = O(followers) — expensive for celebrities.
Fan-out on read (pull model): Store posts by user; at read time merge posts from all followed users. Write = O(1). Read = O(following count) — slow for users following 10K accounts.
Hybrid (Twitter-style)
New postFan-out write<10K followersFan-out readCelebrity accounts
Hybrid: fan-out on write for normal users; celebrities fetched separately at read time. Precompute for active users only.

③ Sharding & consistent hashing

Sharding strategies:
  • Hash sharding: shard = hash(user_id) % N — even spread; changing N requires resharding
  • Range sharding: user_id 1–1M on shard A — range queries easy; hot ranges possible
  • Directory sharding: lookup service maps key → shard — flexible; lookup service is bottleneck
Consistent hashing ring
Key hashClockwise to nodeVirtual nodesEven load
Virtual nodes: each physical node owns multiple points on the ring — better load balance. Adding a node only moves ~1/N keys. Used in: Cassandra, DynamoDB, Redis Cluster, CDNs.

④ Message queues & event streaming

SystemModelOrderingRetention
RabbitMQ / SQSQueue — one consumer per messageSingle consumer: yes; competing: no guaranteeUntil ack / TTL
KafkaLog — multiple consumer groupsPer-partition orderingConfigurable retention (days)
Redis StreamsLightweight logPer streamMemory-bound
Queue decoupling
API Server (producer)
Message Queue / Kafka
Email Worker
Push Worker
Analytics
At-least-once delivery is default — consumers must be idempotent. Dead letter queue (DLQ) for poison messages after N retries. Backpressure: slow consumers → queue depth grows → alert and scale workers.

⑤ Idempotency

Idempotent operation: performing it multiple times has the same effect as once. Critical for retries, network duplicates, and at-least-once queues.
TechniqueHowExample
Idempotency keyClient sends UUID; server stores result keyed by itStripe Idempotency-Key header
Natural idempotencyOperation is inherently safe to repeatPUT /users/123 with full body
DB unique constraintDuplicate insert fails cleanlyUNIQUE(order_id, payment_id)
State checkOnly act if status is PENDINGCharge only if order.status != PAID
Store idempotency keys in Redis/DB with TTL (24–72h). Return cached response on duplicate key. Payment APIs: never double-charge — idempotency is non-negotiable.

⑥ Sagas vs two-phase commit

ApproachMechanismProsCons
2PCCoordinator locks all participants; commit or abortStrong atomicityBlocking, coordinator SPOF, does not scale
Choreography sagaEach service emits events; others reactDecoupled, no coordinatorHard to trace, cyclic risk
Orchestration sagaCentral saga manager calls steps + compensationsClear flow, easier debugOrchestrator is dependency
Saga: book flight + hotel
Book flight ✓Book hotel ✗Compensate: cancel flight
Compensating transactions undo prior steps (cancel reservation, refund). Not all steps are compensatable (email sent). Prefer sagas for microservices; 2PC rare outside databases.

⑦ Circuit breaker

States: Closed (normal) → failures exceed threshold → Open (fail fast, no calls) → after timeout → Half-open (trial request) → success → Closed; failure → Open.
Circuit breaker in call chain
Your Service
Circuit Breaker
Payment API (healthy)
Payment API (down → open)
SettingTypical valuePurpose
Failure threshold5 failures in 10sTrip to open
Open duration30–60sLet dependency recover
Half-open probes1–3 requestsTest recovery
FallbackCached response / queue for retryGraceful degradation
Libraries: Resilience4j (Java), Polly (.NET), Hystrix (legacy). Pair with timeouts — circuit breaker without timeout still hangs threads.

⑧ Rate limiting (companion pattern)

AlgorithmBehaviorUse case
Token bucketBurst allowed up to bucket size; steady refill rateAPI rate limits with burst tolerance
Leaky bucketSmooth output rate regardless of input spikesTraffic shaping
Fixed windowCount requests per window (e.g. per minute)Simple; boundary spike at window edges
Sliding windowRolling count over last N secondsSmoother than fixed window
Distributed rate limiting: Redis INCR + EXPIRE or sliding window in Redis (Lua for atomicity). Return 429 Too Many Requests with Retry-After header. Per-user, per-IP, per-API-key tiers.

⑨ Scenario — notification system patterns

Write path: event → Kafka topic (partitioned by user_id)
Fan-out workers: read event, lookup preferences, enqueue per-channel jobs
Idempotent consumers: dedupe by (user_id, event_id, channel)
Circuit breaker on Twilio/SendGrid — fallback to in-app only
Rate limit: max 10 push/hour/user to prevent spam
Inbox storage: sharded by user_id, sorted by timestamp
Interview script: "I'd use a queue to decouple the write path from delivery, idempotency keys to handle retries, circuit breakers on external providers, and shard the inbox by user_id."

⑩ Revision checklist

  • Named fan-out on write vs read with celebrity/hybrid mitigation
  • Explained sharding strategy and consistent hashing for cache/cluster
  • Used message queue for async decoupling with at-least-once semantics
  • Designed idempotency for payments or duplicate-prone operations
  • Contrasted saga vs 2PC for distributed transactions
  • Described circuit breaker states and fallback behavior
  • Mentioned rate limiting with algorithm choice
  • Mapped patterns to a concrete scenario (feed, payments, notifications)
fan-outshardingqueuesidempotencysagacircuit-breaker