QuizCluster
System DesignMid-Level to Staff / Principal Engineer21 min read

System Design Interview Guide: Complete 2026 Roadmap

From Back-of-the-Envelope Math to Distributed Trade-Offs: A Staff-Level Blueprint for HLD Rounds

Priya Nakamura
Ex-FAANG Staff Engineer & Distributed Systems Interviewer
15+ Years Building Planet-Scale Backend Platforms
Prep Timeline
6 to 10 Weeks
Format
2-3 HLD Rounds (Mid, Senior & Staff/Principal Loops)
Conversion
+81% System Design Round Pass Rate
System Design Interview Guide: Complete 2026 Roadmap
Executive Summary & Key Takeaways

What You Must Master to Clear This Track

  • Always anchor your design in back-of-the-envelope math (QPS, storage, bandwidth) before drawing a single box.
  • Treat CAP theorem as a spectrum of trade-offs, not a checkbox: articulate exactly what you sacrifice and why for each component.
  • Master the 4-step framework: Scope -> Estimate & High-Level Design -> Component Deep-Dive -> Bottlenecks & Resilience.
  • Know sharding, replication, caching, and message queues well enough to justify a specific configuration, not just name-drop them.
  • Practice narrating 2-3 classic systems end-to-end (URL shortener, chat app, news feed) until the trade-off discussion becomes second nature.
Structured Preparation Timeline

Step-by-Step Study Plan

Follow this sequential roadmap designed to take you from core foundations to advanced architecture and mock interviews.

Phase 1 (Weeks 1-3)

Scalability Fundamentals & CAP-Driven Thinking

Foundations: Estimation, Networking & Consistency Theory

Back-of-the-envelope estimation, vertical vs horizontal scaling, DNS/TCP/HTTP fundamentals, CAP theorem, PACELC, and consistency models.

Key Milestones
  • Memorize the core latency numbers (memory vs SSD vs disk vs cross-region network) and practice deriving QPS/storage from DAU figures.
  • Explain CAP theorem trade-offs for at least 3 real databases (DynamoDB, Cassandra, Spanner, PostgreSQL).
  • Understand quorum-based consistency (W + R > N) and read-your-writes guarantees.
Recommended Actions
  • Time yourself doing a 5-minute capacity estimation for a hypothetical 50M DAU service every day.
  • Draw the CAP triangle from memory and place 5 well-known databases on it correctly.
Phase 2 (Weeks 4-6)

Distributed Data & Asynchronous Processing

Data Layer Mastery: Sharding, Replication, Caching & Queues

Database sharding strategies, leader-follower/leaderless replication, caching patterns, consistent hashing, message queues, and rate limiter algorithms.

Key Milestones
  • Implement consistent hashing with virtual nodes to explain minimal data movement on node churn.
  • Compare cache-aside, write-through, and write-back, and diagnose cache stampede scenarios.
  • Implement a token-bucket rate limiter and explain distributed enforcement across multiple app servers.
Recommended Actions
  • Whiteboard a sharded, replicated database topology and narrate a write path and a read path separately.
  • List 3 production incidents caching or queueing could have prevented, and how.
Phase 3 (Weeks 7-9)

The 4-Step Framework Under Time Pressure

Applied HLD Practice & Mock Interviews

Full end-to-end mock designs for a URL shortener, a WhatsApp-style chat system, and a news feed, plus bottleneck and resilience discussions.

Key Milestones
  • Complete at least 8 full 45-minute mock HLD sessions covering distinct system archetypes.
  • Practice articulating single points of failure (SPOF), failover, and multi-region strategy for every design.
  • Record yourself and review pacing: 5 min scope, 10 min estimation/HLD, 20 min deep-dive, 10 min bottlenecks.
Recommended Actions
  • Never let a design go past 10 minutes without drawing a labeled box diagram.
  • Always end with 2-3 proactive bottleneck callouts before the interviewer asks.
Deep-Dive Architecture & Concepts

1. Scalability Fundamentals & Back-of-the-Envelope Estimation

Every credible system design answer starts with numbers. Interviewers use your estimation instincts as a proxy for real-world engineering judgment long before any architecture diagram appears.

Vertical vs Horizontal Scaling

Vertical scaling (bigger machines) is simple but hits hard physical ceilings and creates a single point of failure; horizontal scaling (more machines) requires stateless services, partitioned data, and coordination, but scales near-linearly.

Traffic Estimation (QPS)

Convert Daily Active Users into average requests-per-second, then apply a peak multiplier (typically 2-3x average) to size infrastructure for realistic traffic spikes, not just the daily mean.

Storage & Bandwidth Projection

Estimate storage growth per year from (writes/day x avg payload size x 365) and replication factor, and estimate bandwidth from (requests/sec x avg response size) to size network and CDN egress budgets.

Read-Heavy vs Write-Heavy Workloads

Most consumer systems are read-heavy (100:1 or higher read:write ratios), which justifies aggressive caching and read replicas; write-heavy systems (analytics, IoT ingestion) instead prioritize sharding, batching, and log-structured storage.

Interviewer Insights & Pro Tips
  • Round numbers aggressively (10M DAU, not 9.7M) — precision doesn't matter, order of magnitude does.
  • State every assumption out loud: 'Assuming 20% of DAU are active concurrently, and average session generates 5 write requests...'
Red Flags & Common Pitfalls
  • Spending 15+ minutes on estimation minutiae instead of the 5-10 minutes interviewers expect.
  • Computing storage or QPS and then never using the number again to justify a design decision.
Deep-Dive Architecture & Concepts

2. CAP Theorem, Consistency Models & Data Partitioning

Distributed data is where system design interviews separate candidates who've memorized buzzwords from those who understand the trade-offs of running a database across unreliable networks.

CAP Theorem in Practice

During a network partition, a distributed system must choose Consistency (reject/queue conflicting writes) or Availability (serve possibly-stale data); Partition tolerance is not optional in any real multi-node system, so the real choice is CP vs AP.

PACELC Extension

Even without a partition (Else), you still trade Latency against Consistency: synchronous cross-region replication lowers staleness but raises write latency; async replication does the opposite.

Consistency Models

Strong consistency guarantees every read sees the latest write (Spanner, single-leader RDBMS); eventual consistency (DynamoDB, Cassandra default) allows temporary divergence; causal consistency preserves cause-effect ordering without full linearizability.

Sharding Strategies

Range-based sharding (simple, prone to hotspots on sequential keys), hash-based sharding (uniform distribution, harder range queries), and directory-based sharding (a lookup service maps keys to shards, flexible but adds a dependency).

Replication Topologies

Leader-follower (single write path, simple consistency, follower lag risk), multi-leader (write availability across regions, needs conflict resolution), and leaderless/quorum-based (Dynamo-style, tunable via W+R>N).

Consistent Hashing Ring with Virtual Nodes (Minimal Resharding)
typescript
// Consistent hashing distributes shard/cache keys so that adding or
  // removing a node only remaps ~1/N of keys, instead of a full rehash.
  class ConsistentHashRing {
    private ring = new Map<number, string>();
    private sortedHashes: number[] = [];
  
    constructor(private readonly virtualNodesPerNode: number = 150) {}
  
    private hash(key: string): number {
      let h = 0;
      for (let i = 0; i < key.length; i++) {
        h = (Math.imul(h, 31) + key.charCodeAt(i)) >>> 0; // 32-bit unsigned
      }
      return h;
    }
  
    addNode(nodeId: string): void {
      for (let v = 0; v < this.virtualNodesPerNode; v++) {
        this.ring.set(this.hash(`${nodeId}#${v}`), nodeId);
      }
      this.sortedHashes = Array.from(this.ring.keys()).sort((a, b) => a - b);
    }
  
    removeNode(nodeId: string): void {
      for (let v = 0; v < this.virtualNodesPerNode; v++) {
        this.ring.delete(this.hash(`${nodeId}#${v}`));
      }
      this.sortedHashes = Array.from(this.ring.keys()).sort((a, b) => a - b);
    }
  
    // Finds the first node clockwise from the key's hash position.
    getNode(key: string): string {
      if (this.sortedHashes.length === 0) throw new Error("Ring has no nodes");
      const target = this.hash(key);
      let lo = 0, hi = this.sortedHashes.length - 1;
      if (target > this.sortedHashes[hi]) return this.ring.get(this.sortedHashes[0])!;
      while (lo < hi) {
        const mid = (lo + hi) >>> 1;
        if (this.sortedHashes[mid] < target) lo = mid + 1;
        else hi = mid;
      }
      return this.ring.get(this.sortedHashes[lo])!;
    }
  }
Why it matters: Virtual nodes (100-200 per physical node) smooth out load distribution, and binary search over sorted hash positions gives O(log N) shard lookup with only ~1/N key movement per topology change.
Interviewer Insights & Pro Tips
  • Name the specific consistency guarantee your design needs per data type — e.g., strong consistency for payment ledgers, eventual consistency for like counts.
  • When justifying a shard key, explicitly check for hotspot risk (e.g., sharding by date creates a hot 'today' shard).
Red Flags & Common Pitfalls
  • Claiming a design is 'always consistent and always available' without acknowledging the CAP trade-off during partitions.
  • Picking a shard key based on convenience (auto-increment ID) instead of query access patterns.
Deep-Dive Architecture & Concepts

3. Load Balancing, Caching, Message Queues & Rate Limiting

This is the operational core of nearly every HLD answer: how traffic is distributed, how reads are made fast, how work is decoupled from the request path, and how abuse is contained.

L4 vs L7 Load Balancing

Layer 4 (transport) load balancers route based on IP/port with minimal overhead and high throughput; Layer 7 (application) load balancers inspect HTTP headers/paths, enabling content-based routing, SSL termination, and richer health checks at slightly higher latency.

Caching Patterns

Cache-aside (app checks cache, falls back to DB, then populates cache) is the most common; write-through (write to cache and DB synchronously) simplifies reads at write-latency cost; write-back (write to cache, flush to DB asynchronously) is fastest but risks data loss on cache failure.

Cache Stampede Prevention

When a hot key expires, thousands of concurrent requests can miss simultaneously and hammer the database; mitigate with request coalescing (single-flight), staggered TTLs with jitter, or serving stale-while-revalidate.

Message Queues & Async Processing

Kafka (high-throughput, ordered log, replayable, ideal for event streaming/analytics) vs RabbitMQ/SQS (simpler push-based work queues with per-message ack); use queues to decouple slow or bursty work (email, video encoding, notifications) from the synchronous request path.

Rate Limiting Algorithms

Token bucket (allows controlled bursts, smooth refill), leaky bucket (strictly smooths output rate), fixed window counter (simple but allows 2x burst at window boundaries), and sliding window log/counter (accurate but more memory/compute per request).

Read-Heavy Request Flow: CDN, Load Balancer & Cache-Aside

How a typical read request is served with minimal database load in a scalable web tier.

1
Client -> CDN Edge
DNS/Anycast routes to the nearest PoP; static/cacheable responses are served directly from edge cache (target 85-95% hit ratio).
2
CDN Miss -> L7 Load Balancer
SSL termination and least-connections routing distribute the request across stateless application servers behind health checks.
3
App Server -> Cache-Aside Lookup
The app server checks Redis/Memcached first using the resource key; on a hit, the response returns immediately without touching the database.
4
Cache Miss -> Read Replica Query
The app server queries a database read replica (not the primary) and repopulates the cache with a TTL plus random jitter to avoid synchronized expiry.
5
Async Write-Path Invalidation
Writes go to the primary DB and publish an invalidation/update event so caches converge quickly without blocking the write request.
Token Bucket Rate Limiter (Per-Client, Continuous Refill)
typescript
// Allows short bursts up to 'capacity' while enforcing a long-term
  // average rate of 'refillRatePerSecond' tokens/sec.
  class TokenBucketLimiter {
    private tokens: number;
    private lastRefillMs: number;
  
    constructor(
      private readonly capacity: number,
      private readonly refillRatePerSecond: number
    ) {
      this.tokens = capacity;
      this.lastRefillMs = Date.now();
    }
  
    private refill(): void {
      const now = Date.now();
      const elapsedSeconds = (now - this.lastRefillMs) / 1000;
      if (elapsedSeconds <= 0) return;
      const tokensToAdd = elapsedSeconds * this.refillRatePerSecond;
      this.tokens = Math.min(this.capacity, this.tokens + tokensToAdd);
      this.lastRefillMs = now;
    }
  
    tryConsume(tokensRequested: number = 1): boolean {
      this.refill();
      if (this.tokens >= tokensRequested) {
        this.tokens -= tokensRequested;
        return true; // Allow request
      }
      return false; // Reject with HTTP 429
    }
  }
Why it matters: In production this state lives in Redis (via a Lua script for atomicity) rather than process memory, so every app server instance enforces the same limit for a given client key.
Interviewer Insights & Pro Tips
  • Justify queue choice by delivery semantics needed: at-least-once with idempotent consumers is usually sufficient; exactly-once is expensive and rarely truly necessary.
  • For rate limiting, explicitly state where enforcement happens (API gateway edge vs per-service) and what happens on limiter-store unavailability (fail-open vs fail-closed).
Red Flags & Common Pitfalls
  • Adding Kafka to every design regardless of whether the workload actually needs asynchronous decoupling or ordering guarantees.
  • Forgetting to define cache invalidation strategy, leading to silent staleness bugs the interviewer will probe on.
Deep-Dive Architecture & Concepts

4. The 4-Step HLD Framework & Designing Classic Systems

With the building blocks internalized, the framework below gives you a repeatable structure to apply them under 45 minutes of interview pressure, illustrated with three systems interviewers ask about constantly.

Step 1: Scope & Clarify (5 Min)

Pin down functional requirements (which user actions matter most) and non-functional requirements (scale in DAU, latency targets, availability target like 99.9%, read:write ratio) before drawing anything.

Step 2: Estimate & High-Level Design (10 Min)

Compute QPS/storage/bandwidth, then sketch the top-level block diagram (client -> gateway/LB -> services -> cache/DB -> queue) with just enough boxes to anchor the deep-dive.

Step 3: Component Deep-Dive (20 Min)

Pick the 2-3 hardest components (usually data model, sharding key, and one tricky feature) and go deep: schema, indexes, consistency guarantees, and API contracts.

Step 4: Bottlenecks & Resilience (10 Min)

Proactively call out single points of failure, hot shards, cascading failure risk, and how monitoring/alerting would catch degradation before users do.

Classic Design: URL Shortener

Base62-encode an auto-incrementing or Snowflake-style distributed ID into a 7-character code (62^7 ≈ 3.5 trillion combinations); store the mapping in a key-value store sharded by hash of the short code, cache hot redirects aggressively (redirects are extremely read-heavy), and use HTTP 301 vs 302 deliberately to control analytics vs browser caching.

Classic Design: Chat Application (WhatsApp-style)

Persistent WebSocket connections held by stateful gateway servers, a presence service backed by a fast key-value store, messages written to a per-conversation log and fanned out to online recipients in real time while offline recipients get push notifications; message ordering and delivery receipts require per-conversation sequence numbers, not global ones.

Classic Design: News Feed (Instagram/Twitter-style)

Push (fan-out-on-write) precomputes feeds into each follower's inbox at post time — fast reads, expensive for celebrities with millions of followers; pull (fan-out-on-read) merges sources at request time — cheap writes, slower reads; production systems use a hybrid: push for normal users, pull-and-merge for high-follower accounts.

Interviewer Insights & Pro Tips
  • Say the trade-off out loud even when you commit to one option: 'I'll fan out on write for most users, but pull for celebrity accounts to avoid a write amplification blowup.'
  • Keep a mental timer — if Step 3 is running long, tell the interviewer you're time-boxing and ask which component they'd like prioritized.
Red Flags & Common Pitfalls
  • Jumping directly to 'we'll use microservices and Kafka' before establishing what the functional requirements actually demand.
  • Never returning to Step 1's stated requirements to check whether the final design actually satisfies them.
Real-World Example

Scaling a Ride-Hailing Dispatch Service from 50K to 5M Daily Rides

A mid-size ride-hailing startup's dispatch service — matching riders to nearby drivers — was built as a single-region monolith backed by one PostgreSQL primary. As daily rides grew from 50K to a projected 5M within a year, p99 matching latency had climbed past 4 seconds and the database was CPU-saturated during evening peak hours.

  • 1The team ran capacity estimation first: 5M rides/day implied roughly 350 peak matching-requests/sec, each requiring a geospatial query against active drivers — far beyond what the single Postgres primary could sustain.
  • 2They introduced geo-sharding: the city map was partitioned into hexagonal cells (using a system similar to Uber's H3), with driver location data sharded by cell ID across multiple database nodes to parallelize the geospatial lookups.
  • 3A Redis-backed cache held each cell's currently-active driver set with a 3-second TTL, since driver positions change quickly but a few seconds of staleness was acceptable for the initial matching candidate pool.
  • 4Driver location updates (previously synchronous writes to Postgres) were rerouted through a Kafka topic partitioned by cell ID, decoupling the high-frequency GPS ping ingestion from the matching read path.
  • 5They added a circuit breaker around the matching service so that if the geospatial store degraded, the system fell back to a coarser, cached city-wide driver list rather than failing every request.
  • 6The team ran a 2-week shadow-traffic test, comparing the new sharded path against the legacy monolith before fully cutting over.
Outcome: p99 matching latency dropped from 4.1 seconds to 280 milliseconds, and the dispatch service sustained the full 5M rides/day peak load with headroom to spare, without a single-region database outage during the following six months.
Real-World Interview Questions

Top Must-Know Interview Questions & Model Answers

EstimationMust-Know

Q1: Walk through a back-of-the-envelope capacity estimation for a service with 100M DAU and a 20:1 read:write ratio.

Executive Answer:Derive average and peak QPS from DAU and actions-per-user, then compute storage and bandwidth from payload size and retention, always rounding to convenient order-of-magnitude numbers.
Deep Dive Analysis:
  • 100M DAU x 5 actions/day = 500M requests/day ≈ 5,800 average RPS; applying a 3x peak factor gives ~17,000 RPS at peak.
  • With a 20:1 read:write ratio, roughly 550 write RPS and 5,250 read RPS at peak, which directly justifies heavy read-replica and cache investment.
  • Storage: if each write is ~1KB and there are ~28M writes/day, that's ~28GB/day raw, before replication factor (commonly 3x) and index overhead.
Interviewer Takeaway: Always convert DAU into RPS and storage/day early — every later architecture decision should be traceable back to these numbers.
CAP Theorem & ConsistencyMust-Know

Q2: Explain CAP theorem and place DynamoDB, Cassandra, and a single-leader PostgreSQL setup on the CAP spectrum.

Executive Answer:During a network partition, a system must favor Consistency or Availability; Partition tolerance itself isn't optional in any real distributed system.
Deep Dive Analysis:
  • DynamoDB and Cassandra default to AP: they stay available during partitions by serving potentially stale replicas, using tunable quorums to shift toward consistency if needed.
  • A single-leader PostgreSQL setup with synchronous replication behaves as CP: it rejects writes rather than risk divergence when the leader can't reach a quorum of followers.
  • In practice, most systems are 'CP or AP with tunable knobs' rather than a fixed point — DynamoDB, for instance, offers both eventually-consistent and strongly-consistent reads.
Interviewer Takeaway: Never say a system is 'always CA' — partition tolerance is mandatory once you have more than one node, so the real choice is CP vs AP.
CAP Theorem & ConsistencyHard

Q3: What is PACELC and how does it extend CAP theorem for the non-partition case?

Executive Answer:PACELC says: if Partitioned, choose Availability or Consistency; Else (normal operation), choose Latency or Consistency.
Deep Dive Analysis:
  • Synchronous cross-region replication minimizes staleness (higher consistency) but adds round-trip latency to every write.
  • Asynchronous replication cuts write latency dramatically but allows followers to lag, risking stale reads even without any partition occurring.
  • This explains why systems like Cassandra (PA/EL) and Spanner (PC/EC) make fundamentally different latency/consistency trade-offs even when the network is healthy.
Interviewer Takeaway: CAP only describes partition behavior; PACELC captures the everyday latency-vs-consistency trade-off that matters far more often in production.
CAP Theorem & ConsistencyHard

Q4: Compare strong consistency, eventual consistency, and causal consistency with concrete examples.

Executive Answer:Strong consistency guarantees every reader sees the latest write immediately; eventual consistency allows temporary divergence that resolves over time; causal consistency preserves cause-effect ordering without requiring global ordering.
Deep Dive Analysis:
  • Strong consistency (Spanner's TrueTime, single-leader synchronous replication) is required for account balances and inventory counts.
  • Eventual consistency (DynamoDB default, Cassandra) is acceptable for social media like-counts or view-counts where a few seconds of staleness is invisible to users.
  • Causal consistency ensures a reply to a comment is never shown before the comment itself, even if the two are stored on different replicas — critical for chat and comment threads.
Interviewer Takeaway: Pick the weakest consistency model that still satisfies the product requirement — stronger consistency always costs latency or availability.
Sharding & PartitioningHard

Q5: Design a database sharding strategy for a multi-tenant SaaS product with wildly uneven tenant sizes.

Executive Answer:Use directory-based (lookup-service) sharding so large 'whale' tenants can be isolated on dedicated shards while small tenants are packed together, avoiding both hotspots and wasted capacity.
Deep Dive Analysis:
  • Pure hash-based sharding by tenant ID risks co-locating several large tenants on the same shard by chance, creating a hotspot.
  • A directory service mapping tenant_id -> shard_id allows manual or automated rebalancing of specific tenants without a global rehash.
  • Track per-shard load metrics and set a threshold to trigger tenant migration to a dedicated shard before it becomes a bottleneck.
Interviewer Takeaway: When entities have highly skewed size/load, prefer directory-based sharding over pure hash sharding for rebalancing flexibility.
Sharding & PartitioningMust-Know

Q6: How does consistent hashing minimize data movement compared to naive modulo hashing when nodes are added or removed?

Executive Answer:Naive modulo hashing (key % N) remaps nearly every key when N changes; consistent hashing places nodes and keys on a ring so only keys between the affected node and its neighbor move.
Deep Dive Analysis:
  • With modulo hashing, changing N from 4 to 5 changes the target shard for almost all keys, causing a massive, disruptive data migration.
  • Consistent hashing assigns each node (and virtual replicas of it) a position on a hash ring; a key belongs to the next node clockwise, so adding/removing one node only affects its immediate neighbors' key ranges.
  • Virtual nodes (100-200 per physical node) prevent uneven load distribution that would otherwise occur with only one ring position per node.
Interviewer Takeaway: Consistent hashing bounds data movement to roughly 1/N of keys per topology change — the standard answer whenever elastic scaling of shards or cache nodes comes up.
ReplicationMedium

Q7: Compare leader-follower, multi-leader, and leaderless (quorum-based) replication topologies.

Executive Answer:Leader-follower centralizes writes for simple consistency; multi-leader allows writes in multiple regions at the cost of conflict resolution; leaderless uses quorums for tunable availability and consistency.
Deep Dive Analysis:
  • Leader-follower (PostgreSQL, MySQL): all writes go through one leader, followers replicate asynchronously or synchronously; simple mental model but the leader is a write bottleneck and failover requires promotion.
  • Multi-leader: useful for multi-region active-active writes, but requires conflict resolution (last-write-wins, CRDTs, or application-level merge logic) since two leaders can accept conflicting writes.
  • Leaderless (DynamoDB, Cassandra): writes go to any replica; a write succeeds once W replicas ack, a read queries R replicas; setting W + R > N guarantees overlap and strong-ish consistency.
Interviewer Takeaway: Leaderless with tunable quorums is the go-to answer for multi-region write availability without full multi-leader conflict-resolution complexity.
ReplicationHard

Q8: A read replica in your leader-follower setup is lagging by 4 seconds. What user-facing problems does this cause, and how do you fix them?

Executive Answer:Replication lag breaks read-your-writes consistency — a user who just wrote data may not see it if routed to a stale replica.
Deep Dive Analysis:
  • Symptom: a user updates their profile, refreshes, and sees old data because the read hit a lagging replica.
  • Fix 1: route a user's own reads to the leader (or a replica known to be caught up) for a short window after their write ('read-your-writes' stickiness).
  • Fix 2: attach a version/timestamp to writes and have the client/read path wait for a replica whose applied version meets that watermark.
  • Fix 3: reduce lag itself via faster replication (semi-synchronous), smaller transactions, or dedicated replication bandwidth.
Interviewer Takeaway: Replication lag is invisible until you ask 'what happens if a user reads immediately after writing?' — always test that scenario explicitly.
Load BalancingMedium

Q9: What's the difference between L4 and L7 load balancing, and when would you choose each?

Executive Answer:L4 balances at the transport layer using IP/port with very low overhead; L7 balances at the application layer with visibility into HTTP paths/headers, enabling smarter routing at some latency cost.
Deep Dive Analysis:
  • L4 (e.g., a basic TCP/UDP load balancer) is ideal for raw throughput scenarios like a high-volume game server or a simple internal service mesh hop.
  • L7 (e.g., NGINX, ALB) can route /api/video traffic to a different fleet than /api/search, terminate SSL, and perform content-aware health checks.
  • Most consumer-facing web architectures use L7 at the edge for routing flexibility and L4 (or none) between internal trusted services for speed.
Interviewer Takeaway: Default to L7 at the public edge for routing and SSL termination flexibility; drop to L4 only when raw throughput dominates the decision.
CachingMust-Know

Q10: Compare cache-aside, write-through, and write-back caching strategies.

Executive Answer:Cache-aside is the most common default (lazy population on read miss); write-through keeps cache and DB always in sync at write-time cost; write-back is fastest for writes but risks data loss.
Deep Dive Analysis:
  • Cache-aside: app checks cache, on miss reads DB and populates cache; simple, but the first request after expiry is always slow, and cache/DB can briefly diverge.
  • Write-through: every write updates cache and DB together synchronously; reads are always fresh, but write latency increases and unused data still gets cached.
  • Write-back: writes go to cache immediately and are flushed to DB asynchronously in batches; excellent write latency and reduced DB load, but a cache node crash before flush can lose data.
Interviewer Takeaway: Default to cache-aside unless the workload is write-heavy with tolerance for eventual durability (write-back) or requires read-after-write freshness guarantees (write-through).
CachingHard

Q11: How do you prevent a cache stampede (thundering herd) when a hot key expires?

Executive Answer:Coalesce concurrent misses into a single DB request (single-flight), stagger TTLs with jitter, or serve stale data while asynchronously refreshing in the background.
Deep Dive Analysis:
  • Without protection, thousands of requests missing simultaneously on a hot key can all hit the database at once, potentially causing an outage.
  • Single-flight/request-coalescing: the first miss acquires a per-key lock and fetches from DB; concurrent misses wait on that in-flight fetch instead of issuing duplicate queries.
  • TTL jitter (base TTL +/- random 10%) prevents many keys from expiring in the exact same millisecond after a cold cache warm-up.
  • Stale-while-revalidate: serve the expired-but-still-cached value immediately while one background request refreshes it, trading brief staleness for zero request-path latency spikes.
Interviewer Takeaway: Cache stampede protection is a strong signal of production experience — always mention it when discussing any hot-key caching scenario.
Rate LimitingMust-Know

Q12: Design a rate limiter that must work consistently across a fleet of 50 stateless application servers.

Executive Answer:Move rate-limit state out of process memory into a shared, low-latency store like Redis, using an atomic Lua script or Redis's native command support to avoid race conditions.
Deep Dive Analysis:
  • In-memory per-server counters are wrong at scale — a client could get N requests per server, effectively 50xN total, since state isn't shared.
  • Store a token bucket or sliding-window counter keyed by client ID in Redis; execute the check-and-decrement as a single atomic Lua script to avoid race conditions between concurrent app servers.
  • For very high throughput, an approximate local-then-global scheme (each server gets a local sub-budget synced periodically) trades strict accuracy for lower Redis load.
Interviewer Takeaway: Rate limiting only works correctly at scale if the counter state is centralized and the check-and-decrement operation is atomic.
Rate LimitingHard

Q13: Compare token bucket, leaky bucket, fixed window, and sliding window rate limiting algorithms.

Executive Answer:Token bucket allows controlled bursts with a smooth long-term rate; leaky bucket enforces a strictly smooth output rate; fixed window is simple but allows boundary bursts; sliding window trades memory for accuracy.
Deep Dive Analysis:
  • Token bucket: tokens refill continuously up to a capacity; bursts are allowed as long as tokens are available, which suits bursty client behavior like page loads.
  • Leaky bucket: requests are queued and processed at a constant rate, smoothing bursts entirely but adding queueing delay.
  • Fixed window counter: simplest to implement, but a client can send 2x the limit by timing requests around a window boundary (end of one window + start of next).
  • Sliding window log/counter: tracks exact timestamps (log) or a weighted blend of adjacent windows (counter) for much more accurate enforcement at higher memory/compute cost.
Interviewer Takeaway: Token bucket is the default answer for most APIs because it balances burst tolerance with implementation simplicity; use sliding window when precise enforcement matters more (billing APIs).
Message Queues & Async ProcessingMedium

Q14: When would you choose Kafka over a traditional message queue like RabbitMQ or SQS?

Executive Answer:Kafka excels at high-throughput, ordered, replayable event streams consumed by multiple independent consumers; RabbitMQ/SQS excel at simpler point-to-point task queues with per-message acknowledgment.
Deep Dive Analysis:
  • Kafka retains messages in an ordered, partitioned log for a configurable retention period, so new consumers (e.g., a new analytics pipeline) can replay history — RabbitMQ typically deletes messages once acknowledged.
  • Kafka partitions provide ordering guarantees only within a partition, so choosing a good partition key (e.g., user ID) matters for use cases needing per-entity ordering.
  • RabbitMQ's per-message routing (exchanges, bindings) and easy dead-letter queue support make it simpler for classic task-queue workloads like 'send this one email.'
Interviewer Takeaway: Reach for Kafka when you need a durable, replayable, multi-consumer event log; reach for RabbitMQ/SQS for simpler decoupled task execution.
Message Queues & Async ProcessingHard

Q15: How do you achieve exactly-once-like processing semantics when your message queue only guarantees at-least-once delivery?

Executive Answer:Make the consumer's side-effect idempotent using a unique idempotency key stored durably, so reprocessing the same message multiple times has no additional effect.
Deep Dive Analysis:
  • At-least-once delivery means a consumer crash after processing but before acknowledging will cause redelivery of an already-handled message.
  • Attach a unique idempotency key (e.g., a UUID generated by the producer) to each message; the consumer checks a durable store (DB unique constraint or dedupe cache) before applying the effect.
  • For financial operations, this typically means an 'idempotency_keys' table with a unique constraint, inserted transactionally alongside the business write.
Interviewer Takeaway: True exactly-once delivery across a network is effectively impossible; the practical answer is always at-least-once delivery plus idempotent consumers.
Classic System: URL ShortenerMust-Know

Q16: How would you design a globally distributed URL shortener handling 500M new URLs per month and a 100:1 read:write ratio?

Executive Answer:Generate short codes via a distributed ID generator (e.g., Snowflake) base62-encoded to ~7 characters, store the mapping in a sharded key-value store, and cache redirects aggressively behind a CDN/edge layer.
Deep Dive Analysis:
  • 500M/month ≈ 190 writes/sec average; with 100:1 read:write, that's ~19,000 reads/sec average — heavily read-dominated, justifying an aggressive caching layer.
  • Avoid a single auto-increment counter (write bottleneck, single point of failure); instead use a Snowflake-style ID (timestamp + machine ID + sequence) generated independently per node, then base62-encode it.
  • Store short_code -> long_url in a key-value store sharded by hash of short_code; cache the hottest redirects in Redis/CDN edge, since redirect lookups are the overwhelming majority of traffic.
  • Use HTTP 302 (temporary redirect) by default so click analytics keep flowing through your service, rather than 301 which browsers cache permanently and bypass your servers.
Interviewer Takeaway: URL shorteners are a canonical 'read-heavy, simple data model' design — the interesting depth is entirely in ID generation and cache strategy, not the schema.
Classic System: URL ShortenerMedium

Q17: In a URL shortener, how do you prevent short-code collisions without a global lock on ID generation?

Executive Answer:Use a distributed unique ID scheme (Snowflake) or pre-generated unique key ranges handed out to each server, so no coordination is needed at request time.
Deep Dive Analysis:
  • A naive random 7-character code has a birthday-paradox collision risk that grows quickly at billions of scale, requiring a DB uniqueness check-and-retry loop that adds latency.
  • Snowflake IDs (timestamp bits + machine/worker ID bits + sequence bits) are globally unique by construction with no coordination needed between nodes.
  • Alternative: a central 'key range allocator' hands each app server a block of 1M pre-approved unique IDs to consume locally before requesting the next block.
Interviewer Takeaway: Whenever a design needs globally unique IDs at scale, default to Snowflake-style generation over random-and-retry.
Classic System: Chat ApplicationHard

Q18: Design the real-time messaging architecture for a WhatsApp-style chat application at 200M DAU.

Executive Answer:Use persistent WebSocket connections to stateful gateway servers, a fast presence store, per-conversation message logs, and push notifications for offline delivery, with per-conversation sequence numbers for ordering.
Deep Dive Analysis:
  • Clients hold a persistent WebSocket to a connection-gateway tier; a connection registry (e.g., Redis) maps user_id -> gateway_node so any service can locate where to deliver a message.
  • A message is written durably to a per-conversation log first (source of truth), then the sender's gateway pushes it to the recipient's gateway if online, or triggers a push notification via APNs/FCM if offline.
  • Ordering and delivery receipts (sent/delivered/read) require a per-conversation monotonic sequence number, not a global one, since global ordering across unrelated conversations is unnecessary and expensive to coordinate.
  • Group chats fan out the write to each member's inbox/log; very large groups need the same push-vs-pull trade-off used in news feed design.
Interviewer Takeaway: Chat systems hinge on a durable per-conversation log as source of truth plus a connection registry for live delivery — get those two right and the rest follows.
Classic System: Chat ApplicationMedium

Q19: How do you show accurate 'online/offline' presence for hundreds of millions of chat users without overwhelming your infrastructure?

Executive Answer:Use lightweight periodic heartbeats stored in a fast in-memory store with short TTLs, and fan out presence changes only to a user's active chat partners rather than broadcasting globally.
Deep Dive Analysis:
  • Each connected client sends a heartbeat every 10-30 seconds; the gateway refreshes a TTL-based key (e.g., in Redis) — absence of a heartbeat naturally expires presence to 'offline' without an explicit disconnect event.
  • Never broadcast presence changes to all users; only notify users who have that person in an active conversation or contact list, dramatically reducing fan-out volume.
  • Debounce rapid online/offline flapping (e.g., due to spotty mobile connectivity) by delaying the 'offline' broadcast by a few seconds in case the client reconnects.
Interviewer Takeaway: Presence is a classic 'scope the fan-out' problem — broadcast only to interested parties, and let TTL expiry do the disconnect detection for you.
Classic System: News FeedMust-Know

Q20: Design a news feed system: compare fan-out-on-write (push) vs fan-out-on-read (pull) and when to use a hybrid.

Executive Answer:Push precomputes each follower's feed at post time for fast reads but breaks down for celebrity accounts; pull merges sources at read time, avoiding write amplification but slowing reads; production systems use a hybrid.
Deep Dive Analysis:
  • Fan-out-on-write: when a user posts, the post is inserted into every follower's precomputed feed/inbox; reads are then just a fast lookup, ideal for the 99% of users with a normal follower count.
  • Fan-out-on-read: feeds are assembled on demand by querying and merging each followed account's recent posts; avoids the write-amplification disaster of a celebrity with 50M followers triggering 50M feed writes.
  • Hybrid (used by Twitter/Instagram at scale): push for regular accounts, but celebrity/high-follower posts are excluded from push fan-out and instead merged in at read time for any follower's feed request.
  • Ranking (not just chronological order) typically happens at read time regardless of fan-out strategy, using a separate ranking/ML service.
Interviewer Takeaway: Whenever a 'one-to-many' fan-out has a long-tail power-law distribution (celebrities, viral posts), a pure push model breaks — always propose the hybrid.
API & Data Access PatternsMedium

Q21: How would you paginate a news feed or search results API at scale without using OFFSET-based pagination?

Executive Answer:Use cursor/keyset pagination based on a stable sort key (e.g., timestamp + ID), which avoids the performance degradation and consistency issues of OFFSET/LIMIT on large, frequently-changing datasets.
Deep Dive Analysis:
  • OFFSET-based pagination requires the database to scan and discard all preceding rows, getting progressively slower on deep pages, and can show duplicate/missing items if rows are inserted between page requests.
  • Cursor pagination returns an opaque cursor (typically an encoded last-seen sort key value) that the next request uses in a WHERE clause (e.g., WHERE (created_at, id) < (cursor_time, cursor_id)) to fetch the next page directly via an index.
  • This requires a composite index on the sort columns and works well with infinite-scroll UIs, though it sacrifices the ability to jump directly to an arbitrary page number.
Interviewer Takeaway: Default to cursor-based pagination for any large or high-write-rate dataset; reserve OFFSET pagination for small, mostly-static admin tables.
Distributed TransactionsHard

Q22: Compare 2-Phase Commit (2PC) and the Saga pattern for distributed transactions across microservices.

Executive Answer:2PC provides atomicity via a blocking coordinator protocol but doesn't scale well and risks blocking on coordinator failure; Saga achieves eventual consistency via a sequence of local transactions with compensating actions, trading strict atomicity for availability and scalability.
Deep Dive Analysis:
  • 2PC: a coordinator asks all participants to 'prepare' (lock resources), then commits only if all vote yes; if the coordinator crashes after prepare, participants can be left blocked holding locks indefinitely.
  • Saga: each service performs its local transaction and publishes an event/command triggering the next step; if a later step fails, previously completed steps are undone via explicit compensating transactions (e.g., refund payment after inventory reservation fails).
  • Sagas are either choreography-based (services react to each other's events, no central coordinator) or orchestration-based (a central saga orchestrator issues each step and handles failures).
Interviewer Takeaway: In microservices architectures, Saga is almost always preferred over 2PC because it avoids long-lived cross-service locks and scales horizontally.
Distributed TransactionsHard

Q23: What is the outbox pattern and what problem does it solve when publishing events after a database write?

Executive Answer:The outbox pattern writes the business change and an outgoing event record to the same local database transaction, then a separate relay process publishes the event to the message broker, avoiding the dual-write inconsistency of writing to a DB and a queue separately.
Deep Dive Analysis:
  • Writing to the database and publishing to Kafka/RabbitMQ as two separate operations risks one succeeding and the other failing (e.g., DB commits but the broker publish fails, or vice versa), silently losing events.
  • The outbox pattern inserts an 'event to publish' row into an outbox table within the same ACID transaction as the business write, guaranteeing atomicity.
  • A separate relay (polling the outbox table, or using change-data-capture like Debezium reading the DB write-ahead log) asynchronously publishes outbox rows to the broker and marks them sent.
Interviewer Takeaway: Whenever a design needs 'write to DB and notify other services' to be atomic, the outbox pattern is the standard answer — never rely on a bare dual-write.
Databases & IndexingMedium

Q24: Explain the difference between a B-tree index and an LSM-tree, and when each is preferred.

Executive Answer:B-trees optimize for balanced read/write performance with in-place updates (typical RDBMS default); LSM-trees batch writes sequentially and optimize for very high write throughput at the cost of read amplification, common in NoSQL/wide-column stores.
Deep Dive Analysis:
  • B-trees (PostgreSQL, MySQL InnoDB) update pages in place, giving good point-lookup performance but requiring random disk I/O on writes, which becomes a bottleneck under very high write volume.
  • LSM-trees (Cassandra, RocksDB, HBase) buffer writes in an in-memory memtable, flush to immutable sorted SSTables sequentially, and periodically compact them — this converts random writes into sequential ones, dramatically improving write throughput.
  • The trade-off is read amplification: a read may need to check the memtable and multiple SSTables, mitigated with Bloom filters to quickly skip SSTables that can't contain a key.
Interviewer Takeaway: Choose LSM-backed stores for write-heavy ingestion pipelines (logs, metrics, IoT); choose B-tree-backed RDBMS when read latency predictability and in-place updates matter more.
Coordination & ConsensusHard

Q25: How would you design a distributed lock, and what pitfalls exist with a naive Redis SETNX-based implementation?

Executive Answer:A distributed lock needs an atomic acquire-with-expiry, safe release only by the owner, and awareness that a single Redis node is a single point of failure — the Redlock algorithm addresses the latter using a quorum of independent Redis instances.
Deep Dive Analysis:
  • A naive SET key value NX EX ttl acquires a lock atomically with auto-expiry (preventing permanent deadlock if the holder crashes), but releasing it must verify ownership (e.g., compare-and-delete via a Lua script) to avoid releasing another client's lock.
  • A single Redis instance is a single point of failure and can lose the lock state on failover, letting two clients believe they hold the same lock simultaneously.
  • Redlock acquires the lock against a majority of N independent Redis nodes within a bounded time; it's a partial mitigation, though it remains a debated approach for correctness under clock drift and GC pauses.
  • For strict correctness guarantees, a consensus system like ZooKeeper or etcd (using sequential ephemeral nodes) is generally preferred over ad hoc Redis locking.
Interviewer Takeaway: Any distributed lock needs auto-expiry plus ownership-checked release at minimum; for true correctness guarantees, reach for a consensus store (ZooKeeper/etcd) over single-node Redis.
Coordination & ConsensusHard

Q26: At a high level, how does the Raft consensus algorithm elect a leader and replicate a log entry?

Executive Answer:Nodes start as followers and become candidates after an election timeout with no leader heartbeat; a candidate wins by getting votes from a majority, then replicates log entries to followers and commits once a majority acknowledges.
Deep Dive Analysis:
  • Each node has a randomized election timeout; if no heartbeat arrives from a leader in time, it becomes a candidate, increments its term, and requests votes from peers.
  • A candidate becomes leader once it receives votes from a majority of nodes; term numbers prevent stale leaders from a network partition from overriding a newer leader.
  • The leader appends new entries to its log and replicates them to followers; an entry is considered committed once a majority of nodes have persisted it, at which point it's safe to apply and respond to the client.
Interviewer Takeaway: You rarely implement Raft yourself in an interview, but recognizing 'leader election + majority-quorum commit' is what underlies etcd, ZooKeeper (ZAB), and Kafka's controller election is a strong signal.
Multi-Region ArchitectureHard

Q27: How would you design a multi-region active-active architecture, and how do you handle conflicting concurrent writes to the same record?

Executive Answer:Each region accepts local writes for low latency, asynchronously replicates to other regions, and conflicts are resolved via last-write-wins timestamps, version vectors, or CRDTs depending on how much data loss is acceptable.
Deep Dive Analysis:
  • Active-active reduces write latency for users in each region and improves availability (a whole region can go down without a global outage), but multiple regions can accept conflicting writes to the same key concurrently.
  • Last-write-wins (LWW) using synchronized clocks (or hybrid logical clocks) is simple but can silently discard a legitimate concurrent update.
  • CRDTs (Conflict-free Replicated Data Types) allow certain data structures (counters, sets) to merge deterministically without data loss, at the cost of restricting the data model.
  • For strictly consistent data (e.g., financial ledgers), active-active is often avoided in favor of a single-region-write, multi-region-read topology instead.
Interviewer Takeaway: Active-active always implies a conflict-resolution strategy — naming one (LWW, CRDT, or application-level merge) is what separates a real answer from a hand-wave.
Observability & ReliabilityMedium

Q28: What SLIs, SLOs, and monitoring would you propose for a newly designed payments API?

Executive Answer:Define SLIs (request latency p99, error rate, availability) measured continuously, set SLOs as targets (e.g., 99.95% success, p99 < 300ms) with an error budget, and instrument metrics/logs/traces to detect and diagnose violations.
Deep Dive Analysis:
  • SLI examples: percentage of successful (2xx/4xx expected) responses, p50/p95/p99 latency, and queue depth for async payment processing.
  • SLOs translate SLIs into targets tied to business impact (e.g., 99.95% success over 30 days) and define an error budget that, once exhausted, should pause risky deploys.
  • Instrumentation needs all three pillars: metrics (aggregated dashboards/alerts), structured logs (debugging specific failed transactions), and distributed traces (following one request across payment, fraud-check, and ledger services).
Interviewer Takeaway: Always tie proposed metrics back to user-facing behavior and a concrete numeric target — vague 'we'll add monitoring' answers under-deliver in senior interviews.
Architecture Trade-OffsMedium

Q29: How do you decide between a monolith and microservices for a new product, and what does 'premature microservices' cost a team?

Executive Answer:Start with a well-modularized monolith unless you already have clear team-scaling or independent-deployment needs; premature microservices add network latency, operational complexity, and distributed-debugging overhead before the org is large enough to benefit.
Deep Dive Analysis:
  • Microservices genuinely help when independent teams need to deploy independently, or when components have wildly different scaling/resource profiles that benefit from isolated scaling.
  • Premature adoption forces every feature to cross network boundaries, introduces distributed transaction complexity (see Saga/2PC), and multiplies the operational surface area (service discovery, per-service monitoring, versioned contracts) for a team too small to absorb it.
  • A common pragmatic path is 'modular monolith first' — enforce clean internal module boundaries so a future extraction into services is a refactor, not a rewrite.
Interviewer Takeaway: Justify microservices by organizational/scaling need, not by default — interviewers reward candidates who resist over-engineering.
CDN & Edge DeliveryMedium

Q30: Design a global CDN caching strategy for a video streaming platform's static assets and thumbnails.

Executive Answer:Push immutable, content-hashed assets to CDN edge PoPs with long TTLs and cache-busting via filename versioning, while keeping dynamic/personalized content out of the shared CDN cache entirely.
Deep Dive Analysis:
  • Content-hash the asset filename (e.g., thumbnail.a1b2c3.jpg) so any content change produces a new URL, allowing an effectively infinite TTL without stale-content risk.
  • Use a tiered cache hierarchy (edge PoP -> regional cache -> origin) so a cache miss at the edge doesn't always travel all the way back to origin, reducing origin load and cross-region latency.
  • Never cache personalized or authenticated responses at a shared CDN layer unless using private, per-user cache keys — otherwise one user's cached response can leak to another.
Interviewer Takeaway: Immutable, content-hashed URLs plus a tiered cache hierarchy is the standard pattern for maximizing CDN hit ratio without staleness or leakage risk.
Sharding & PartitioningMedium

Q31: What's the difference between vertical partitioning and horizontal partitioning (sharding), and when would you use vertical partitioning first?

Executive Answer:Vertical partitioning splits a schema by columns/tables (e.g., separating rarely-used large columns into their own table), while horizontal partitioning (sharding) splits rows across multiple database instances; vertical partitioning is often the simpler first step before full sharding is needed.
Deep Dive Analysis:
  • Vertical partitioning moves large or infrequently accessed columns (e.g., a user's biography text, profile image blob) into a separate table, keeping the hot row narrow and cache-friendly.
  • It can also mean splitting a database by service/domain (users DB, orders DB, inventory DB) — a natural precursor to a services architecture.
  • Horizontal sharding is reached for once a single machine can no longer hold the working set or handle the write throughput of one logical table, requiring a shard key and routing logic.
Interviewer Takeaway: Exhaust vertical partitioning and read replicas before reaching for horizontal sharding — sharding adds significant application-level complexity (cross-shard joins/transactions).
Common Mistakes

Mistakes That Sink Otherwise Strong Candidates

Diving straight into drawing boxes before clarifying functional and non-functional requirements.

Why it happens: Candidates feel pressure to demonstrate architecture knowledge immediately and treat clarifying questions as wasted time.

The fix: Spend the first 5 minutes explicitly listing functional requirements and non-functional targets (scale, latency, availability) — every later decision should trace back to one of these.

Estimating capacity numbers and then never referencing them again in the design.

Why it happens: Estimation is treated as a ritual checkbox rather than an input that should actually change architecture decisions.

The fix: Explicitly connect each number to a decision: 'At 17K peak RPS, a single DB instance can't serve this, so we need read replicas and caching.'

Defaulting to microservices, Kafka, and a dozen databases for a problem that a well-indexed monolith could handle.

Why it happens: Buzzword-driven design feels impressive and mirrors what candidates read in big-tech engineering blogs, regardless of actual scale requirements.

The fix: Justify every additional piece of infrastructure against the stated scale; explicitly say when a simpler option (a monolith, a single sharded DB) is sufficient.

Claiming a design is simultaneously always consistent and always available with no trade-off.

Why it happens: CAP theorem is often memorized as a slogan rather than internalized as a real engineering constraint.

The fix: For every stateful component, explicitly state what happens during a network partition or node failure, and which property (C or A) is sacrificed.

Choosing a sharding key or database purely for implementation convenience (e.g., auto-increment ID) instead of query patterns.

Why it happens: It feels like a minor implementation detail rather than a decision the interviewer expects to be justified.

The fix: Choose the shard key based on the dominant access pattern (e.g., shard by user_id if 90% of queries filter by user) and explicitly check for hotspot risk.

Introducing a cache with no discussion of invalidation, TTL, or stampede protection.

Why it happens: Caching is treated as a free performance win rather than a source of a whole new class of staleness and thundering-herd bugs.

The fix: Always pair 'we'll cache X' with an explicit invalidation strategy, TTL policy, and stampede mitigation (jitter, single-flight, or stale-while-revalidate).

Never mentioning single points of failure, replication, or failover for any stateful component.

Why it happens: Time pressure pushes candidates to focus entirely on the happy path and leave resilience for 'if there's time.'

The fix: Reserve the final 10 minutes specifically for SPOF and failure-mode discussion, even if it means cutting a deep-dive short.

Treating the interview as a monologue instead of a conversation, ignoring interviewer hints or redirects.

Why it happens: Nervousness leads candidates to stick rigidly to a memorized design template regardless of the signals they're given.

The fix: Pause after each major decision to check in ('Does this direction make sense, or would you like me to focus elsewhere?') and actually adapt based on the answer.

Cheat Sheet

Quick-Reference Cheat Sheet

Back-of-the-Envelope Estimation
Average QPS(Daily Active Users x Actions/User) / 86,400 seconds
Peak QPSAverage QPS x 2-3x peak factor
Storage per yearWrites/day x Avg payload size x 365 x Replication factor
BandwidthRequests/sec x Avg response size
Typical read:write ratio (social/consumer apps)10:1 to 100:1
Common availability targets99.9% ≈ 8.7 hrs/yr downtime; 99.99% ≈ 52 min/yr
Latency Numbers Every Engineer Should Know
L1/L2 cache reference~1 ns
Main memory reference~100 ns
Redis/Memcached round trip (same datacenter)~0.5-1 ms
Read 4KB randomly from SSD~150 microseconds
Disk seek (spinning HDD)~10 ms
Same-datacenter network round trip~0.5 ms
Cross-region network round trip (e.g., US to Europe)~150 ms
CAP & Consistency Models
Quorum consistency conditionW + R > N (guarantees read/write overlap)
CP examplesHBase, MongoDB (default), Spanner, single-leader RDBMS
AP examplesDynamoDB, Cassandra, CouchDB
Strong consistency use casePayments, inventory counts, auth tokens
Eventual consistency use caseLike counts, view counts, activity feeds
Caching Patterns & Eviction
Cache-asideApp-managed; read-populate-on-miss; most common default
Write-throughSync write to cache + DB; always fresh, higher write latency
Write-backAsync flush to DB; fastest writes, durability risk
Eviction policy defaultLRU (Least Recently Used); LFU for skewed hot-key workloads
TTL jitterBase TTL +/- 5-10% random to avoid synchronized expiry
Stampede protectionSingle-flight lock or stale-while-revalidate
Rate Limiting Algorithms
Token bucketAllows bursts up to capacity; smooth refill rate; most common default
Leaky bucketStrictly constant output rate; adds queueing delay
Fixed window counterSimple; allows up to 2x burst at window boundary
Sliding window logExact accuracy; O(N) memory per client
Sliding window counterWeighted blend of adjacent windows; good accuracy/memory balance
Database Scaling Defaults
Default replication factor3 (tolerates 1 node loss with quorum intact)
Sharding strategiesRange-based, hash-based, directory/lookup-based
Index structure for read-heavy OLTPB-tree
Index structure for write-heavy ingestionLSM-tree (SSTables + compaction)
Connection pool sizing heuristic~(CPU cores x 2) + effective spindle/disk count
Assessment Integration

Recommended Practice Quizzes on QuizCluster

Test your retention and prepare for timed live coding and MCQ technical screening rounds:

Frequently Asked Questions

Do I need to write actual code in a system design interview?

Rarely, and only in small, targeted amounts — e.g., a core API signature, a rate limiter's check function, or a database schema DDL. The interview is primarily evaluating architecture, trade-off reasoning, and communication, not implementation.

How much time should I spend on back-of-the-envelope math?

5-10 minutes out of a 45-minute round. The goal is to derive numbers that inform later decisions (e.g., 'this justifies sharding' or 'this doesn't need a queue yet'), not to produce perfectly precise figures.

Is it better to go broad across many components or deep on just one or two?

Depth wins. Interviewers consistently rate candidates higher when they pick 2-3 components (usually the data model, a sharding/consistency decision, and one tricky feature) and reason through them thoroughly, rather than superficially naming every buzzword.

What's the single most common reason strong engineers fail system design rounds?

Skipping the requirements-clarification step and jumping straight to a familiar architecture (usually microservices plus Kafka) without confirming it actually matches the stated scale and constraints of the problem.

Explore Other Preparation Guides

Software Engineering
How to Prepare for SDE Interview: Complete 2026 Roadmap
16 min readRead →
Java Ecosystem
How to Prepare for Java Developer Interview: Core to Spring Boot & JVM
18 min readRead →
Microservices & Distributed Systems
How to Prepare for Microservices Developer Interview: Distributed Architecture & Cloud
17 min readRead →
Databases
SQL Interview Questions & Preparation Guide: Beginner to Advanced
17 min readRead →
Programming Languages
Python Interview Preparation: Complete Guide for 2026
17 min readRead →
Frontend Engineering
React Interview Preparation: React 19 & Next.js Guide
17 min readRead →
Cloud & DevOps
Kubernetes Interview Guide: Architecture, Pods, Networking & Troubleshooting
17 min readRead →
Cloud & DevOps
AWS Solutions Architect Interview Guide: Real Architecture Scenarios
17 min readRead →
Databases
Database System Design: SQL vs NoSQL, Sharding, Replication & Indexing
19 min readRead →
Microservices & Distributed Systems
Kafka Interview Guide: Architecture, Consumers, Partitions & Exactly-Once Semantics
17 min readRead →
Backend Engineering
REST API Design Interview Guide: Authentication, Pagination, Versioning & Rate Limiting
15 min readRead →
Cloud & DevOps
Docker Interview Guide: Images, Containers, Networking & Production Debugging
15 min readRead →
Programming Languages
JavaScript & TypeScript Interview Guide: From Closures to the Event Loop
17 min readRead →
Backend Engineering
Node.js Backend Interview Guide: Event Loop, Streams, APIs & Scaling
17 min readRead →
Databases
Redis System Design Guide: Caching, Eviction, Persistence & Distributed Locks
17 min readRead →
Software Engineering
Concurrency Interview Guide: Threads, Locks, Race Conditions & Deadlocks
17 min readRead →
Software Engineering
Dynamic Programming Patterns: How to Recognize and Solve DP Problems
17 min readRead →