Skip to content

PUBLIC QUESTION PREVIEW

System Design interview questions

HLD, LLD, scalability, design patterns — how to build systems that last.

Showing 12 of 63 source questions. Sample answers are study material, not employer-specific hiring guidance.

How to work through this preview

Attempt each question before reading its answer. For a concept, give a definition and a concrete example. For code, state constraints, walk through a small input, and check complexity. For design, separate requirements from assumptions and explain failure handling. Use real situations for behavioral answers.

QUESTION 1 / medium / system design

How would you design a URL shortener like bit.ly? Walk through the key components.

Sample answer

Requirements: create short URL, redirect to original, analytics (optional). ~100M URLs created/day, ~10B redirects/day (read-heavy 100:1). Key components: 1. Short code generation: Base62 encoding of an auto-increment ID (or distributed ID like Snowflake). 7 chars = 62^7 = 3.5 trillion unique URLs. 2. Storage: KV store (Redis for hot URLs, DynamoDB/Cassandra for persistence). Schema: shortCode → {originalUrl, createdAt, userId} 3. Redirect flow: GET /{code} → cache lookup → DB lookup → 301/302 redirect 4. CDN: cache popular redirects at edge. Use 302 (temporary) for analytics tracking; 301 (permanent) skips server on repeat visits. 5. Scale: read replicas for DB, Redis cache with LRU eviction, rate limiting on creation API.

Hints to guide your next attempt

  • How do you generate short codes? How do you handle redirects at scale?
  • Think about reads vs. writes ratio
Read the supplied solution walkthrough

1. Clarify Requirements

Functional: create short URL, redirect to original URL, optional analytics (click count, geography). Non-functional: high availability (99.99%), low latency redirects (<10ms), scale to 100M URLs/day created, 10B redirects/day. Read:Write ratio → ~100:1 (read-heavy system). URL lifespan: permanent or expiring?

2. Capacity Estimation

Writes: 100M URLs/day = ~1,160 URLs/sec Reads: 10B redirects/day = ~115,000 redirects/sec Storage: 100M URLs × 500 bytes = 50GB/day. Over 5 years = ~90TB (manageable with object storage). Cache: 80/20 rule — cache top 20% of URLs = ~10GB hot cache needed.

3. High-Level Design

Components: - API servers: POST /shorten → returns short code. GET /{code} → 302 redirect. - Short code generation: Base62(auto-increment ID) or Snowflake ID → 7 chars = 62^7 = 3.5T unique URLs. - Database: shortCode → {originalUrl, userId, createdAt, expiresAt}. Use NoSQL (Cassandra/DynamoDB) for write throughput. - Cache layer: Redis with LRU eviction. Cache popular codes — avoids DB hit on 99% of redirects. - CDN: cache redirects at edge for globally distributed low latency.

4. Deep Dive & Trade-offs

301 vs 302 redirect: - 301 Permanent: browser caches it — no future server hit. Better performance, but can't track clicks. - 302 Temporary: hits server every time — enables analytics. Use 302 if analytics required. Collision prevention: use DB unique constraint on shortCode. On collision, regenerate. Custom URLs: allow users to pick their own short code. Check availability first, store separately. Deletion/expiry: soft delete with expiresAt field. Background job cleans up expired entries. Analytics: async — write click events to a Kafka topic → Flink/Spark processes → analytics DB.

Source tags: system-design / url-shortener / hld / caching

QUESTION 2 / medium / conceptual

What is the CAP theorem? Explain with examples of databases that choose CP vs AP.

Sample answer

CAP theorem: in a distributed system, during a network partition you must choose between Consistency and Availability (Partition tolerance is always required — networks fail). CP (Consistency + Partition tolerance): returns error/timeout rather than stale data during partition. Examples: HBase, Zookeeper, MongoDB (with write concern majority). Use for: banking, inventory systems where stale reads are unacceptable. AP (Availability + Partition tolerance): always returns data (possibly stale) during partition. Examples: Cassandra, DynamoDB, CouchDB. Use for: social feeds, shopping carts, DNS — where availability matters more than perfect consistency. In practice: most systems use "eventual consistency" (AP with convergence) rather than strict CP.

Hints to guide your next attempt

  • You can only guarantee 2 of 3: Consistency, Availability, Partition Tolerance
  • Network partitions are inevitable in distributed systems

Source tags: cap-theorem / consistency / availability / distributed-systems

QUESTION 3 / easy / conceptual

What is the Singleton design pattern? When is it useful and when is it a problem?

Sample answer

Singleton ensures only one instance of a class exists and provides a global access point. Thread-safe implementation (Java): public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) instance = new Singleton(); } } return instance; } } Use for: DB connection pool, config manager, logger, thread pool. Problems: hard to unit test (global state), violates SRP, hidden dependencies, difficult to mock. Prefer dependency injection — pass the single instance as a constructor argument rather than accessing it globally.

Hints to guide your next attempt

  • One instance, global access point
  • Thread safety issue with lazy initialization

Source tags: singleton / design-pattern / thread-safety / lld

QUESTION 4 / medium / conceptual

What is consistent hashing? Why is it used in distributed systems?

Sample answer

Consistent hashing solves the node scaling problem in distributed caches/databases: when you add/remove a server, traditional modulo hashing (key % N) remaps almost all keys — expensive. How it works: 1. Map all servers onto a hash ring (0 to 2^32) 2. Each key is mapped to the nearest server clockwise on the ring 3. When a server is added/removed, only the keys between it and its predecessor move Adding a server: only the keys between the new server and its predecessor migrate. Removing a server: only that server's keys migrate to its successor. Virtual nodes: each physical server owns multiple points on the ring, improving load distribution. Used in: Amazon DynamoDB, Apache Cassandra, Redis Cluster, CDN routing, load balancers. Without consistent hashing: adding a 4th server to a 3-server pool remaps 75% of keys. With consistent hashing: only ~25% of keys move.

Hints to guide your next attempt

  • Minimise data movement when nodes are added or removed
  • Hash ring with virtual nodes

Source tags: consistent-hashing / distributed-systems / caching / scalability

QUESTION 5 / medium / system design

How would you design a rate limiter? What algorithms exist?

Sample answer

Rate limiter controls how many requests a client can make in a time window. Algorithms: Token Bucket: tokens added at a fixed rate. Each request consumes a token. Allows bursts up to bucket size. Common in APIs. Sliding Window Log: store timestamp of each request in Redis sorted set. Count requests in the last N seconds. Accurate but memory-intensive. Sliding Window Counter: hybrid — store count for current and previous window, calculate weighted count. Good balance of accuracy and memory. Fixed Window Counter: simple — increment counter per window (per minute). Reset at window boundary. Problem: 2x the limit can pass around window boundary. Implementation with Redis: - Token bucket: Redis DECRBY with TTL per key - Sliding window: ZADD + ZCOUNT + EXPIRE - Cluster: use Redis Lua scripts for atomic operations Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. Return 429 Too Many Requests when exceeded. Edge considerations: per-user vs per-IP vs per-endpoint, distributed rate limiting across API gateway nodes.

Hints to guide your next attempt

  • Token bucket vs sliding window vs fixed window
  • Where to store state — Redis?
Read the supplied solution walkthrough

1. Requirements

Functional: limit requests per user/IP per time window; return 429 when exceeded; configurable limits per API route. Non-functional: low latency (< 2ms overhead), high availability, correct under concurrent load.

2. Algorithm Choice

Token Bucket: tokens replenish at fixed rate; burst allowed up to bucket capacity. Best for most APIs. Sliding Window: accurate, no boundary spikes, but more memory. Fixed Window: simplest but allows 2x burst around boundary.

3. Storage Layer

Redis for distributed counter: INCR + EXPIRE (fixed window), or ZADD + ZCOUNT (sliding window log). Lua script for atomicity: check + increment in one atomic operation.

4. Architecture

Place rate limiter at API Gateway / reverse proxy (Kong, Nginx, AWS API Gateway). Multi-layer: IP-level at gateway, user-level in application middleware. Headers: X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After.

Source tags: rate-limiting / token-bucket / sliding-window / redis / system-design

QUESTION 6 / hard / conceptual

What is CQRS and Event Sourcing? When would you use them together?

Sample answer

CQRS (Command Query Responsibility Segregation): separate the write model (commands that change state) from the read model (queries that return data). Benefits: read and write models can be optimised independently. Write model normalised for consistency; read model denormalised for fast queries. Scale reads and writes independently. Event Sourcing: instead of storing current state, store the sequence of events that led to it. State = replay of all events. Order { Status: Shipped } → instead, store: [OrderPlaced, PaymentReceived, OrderShipped] Benefits: full audit trail, temporal queries ("what was the state on date X?"), event replay for bug investigation, event-driven integration. CQRS + Event Sourcing together: - Commands generate domain events - Events stored in event store (append-only) - Read model projections rebuild from event stream - Projections can be rebuilt any time Trade-offs: - Increased complexity — justifiable only for complex domains - Eventual consistency between write and read models - Event schema evolution is hard Not every system needs this — simple CRUD apps don't.

Hints to guide your next attempt

  • CQRS = separate read and write models
  • Event Sourcing = store events, not state

Source tags: cqrs / event-sourcing / architecture / system-design

QUESTION 7 / hard / system design

How would you design a real-time notification system (push, email, SMS)?

Sample answer

A notification system must handle: multiple channels (push, email, SMS), high throughput, delivery guarantees, and user preferences. Core components: 1. Notification Service: API to trigger notifications. Validates, enriches, and publishes to message queue. 2. Message Queue (Kafka/SQS): decouples producers from consumers. Enables retry, fan-out to multiple channels. 3. Channel Workers: separate services per channel. - Push: FCM (Android), APNs (iOS) - Email: SendGrid, SES - SMS: Twilio, SNS 4. Template Service: store and render notification templates. 5. User Preference Service: "do not disturb", channel preferences, opt-outs. 6. Delivery Tracking DB: status per notification (sent, delivered, failed, read). Flow: trigger event → Notification Service → Kafka topic per channel → worker pulls → provider API → update delivery status. Reliability: - Retry with exponential backoff for failed deliveries - Dead letter queue for exhausted retries - Idempotency keys to prevent duplicate sends Scale: Kafka partitioned by userId for ordering. Workers horizontally scalable.

Hints to guide your next attempt

  • Decouple event production from delivery
  • Different channels need different providers
Read the supplied solution walkthrough

1. Requirements

Functional: send push/email/SMS notifications; user preference management; delivery tracking. Non-functional: 99.9% delivery rate, low latency for push (<5s), high throughput (10M notifications/day).

2. Core Design

Notification API → validate & enrich → publish to Kafka (one topic per channel: notifications.push, notifications.email, notifications.sms). Worker consumers pull from Kafka → call provider API → update delivery status in DB.

3. Reliability

Retry with exponential backoff (3 attempts). Dead letter queue after exhaustion. Idempotency key per notification — prevents duplicate sends on retry. At-least-once delivery; idempotent providers handle duplicates.

4. User Preferences & Scale

Preference service: opt-out flags, quiet hours, channel priority. Scale: partition Kafka by userId for per-user ordering. Workers scale horizontally. Rate limiting per provider (SMS carriers throttle). Priority queue for critical alerts.

Source tags: notification-system / kafka / push-notifications / system-design

QUESTION 8 / easy / conceptual

What is the difference between horizontal and vertical scaling? When would you choose each?

Supplied choices

  1. Horizontal scaling means upgrading hardware; vertical scaling means adding more machines
  2. Vertical scaling is always preferable as it avoids distributed systems complexity
  3. Vertical scaling adds resources to one machine; horizontal scaling adds more machines — horizontal requires stateless design and load balancing
  4. Both produce identical results; the choice is purely cost-based

Source answer choice: C. Vertical scaling adds resources to one machine; horizontal scaling adds more machines — horizontal requires stateless design and load balancing

Sample answer

Vertical scaling (scale up): add more resources to the same machine — bigger CPU, more RAM, faster disk. Simple, no code changes needed. Hard limit: the biggest machine available. Single point of failure. Horizontal scaling (scale out): add more machines, distribute load with a load balancer. No theoretical limit. Fault-tolerant (one node fails, others continue). Requires stateless application design. Challenges with horizontal scaling: - Session state: must be stored externally (Redis, DB) not in-process - Sticky sessions or distributed caching for consistency - Database: horizontal scaling is harder — read replicas (easy), sharding (complex) Choosing: - Start with vertical — simpler, cheaper at small scale - Go horizontal when: vertical limit hit, need fault tolerance, need geographic distribution - Stateless apps (REST APIs) scale horizontally trivially - Stateful apps (game servers, WebSockets) need session affinity

Hints to guide your next attempt

  • Scale up vs scale out
  • Stateless services are easy to scale horizontally

Source tags: scaling / horizontal / vertical / load-balancer / system-design

QUESTION 9 / hard / conceptual

What is database sharding? What are the common sharding strategies and their trade-offs?

Sample answer

Sharding splits a large database into smaller partitions (shards), each on a different server. Enables horizontal scaling of writes and storage beyond what a single DB can handle. Sharding strategies: Range-based: shard by range of shard key (userId 1–1M → shard 1). Simple but can cause hot spots if data is skewed. Hash-based: hash(key) % N determines shard. Even distribution. Consistent hashing avoids full redistribution on resize. Directory-based: a lookup table maps each key to its shard. Flexible but the directory is a bottleneck and SPOF. Geographical: shard by region. Reduces latency, meets data residency requirements. Challenges: - Cross-shard queries/JOINs: avoid or denormalise - Cross-shard transactions: sagas or 2PC (expensive) - Re-sharding: moving data when a shard fills up - Shard key choice is permanent and critical — bad key = uneven shards Alternatives to sharding (try first): read replicas, caching, connection pooling, query optimization, vertical scaling. Sharding adds significant operational complexity.

Hints to guide your next attempt

  • Sharding = split data across multiple DBs
  • Shard key choice determines everything

Source tags: sharding / database / distributed-systems / scalability

QUESTION 10 / medium / conceptual

What is a message queue? When would you use Kafka vs RabbitMQ?

Sample answer

Message queues decouple producers and consumers, enabling async processing, load levelling, and fault tolerance. RabbitMQ (traditional message broker): - Messages are consumed and deleted (typically) - Push-based delivery to consumers - Complex routing: direct, fanout, topic, headers exchanges - Low latency, designed for transient task queues - Good for: task queues (send email, resize image), RPC patterns, complex routing Kafka (distributed event streaming platform): - Messages are retained on disk for a configurable period (days to forever) - Consumers pull and track their own offset — can re-read or replay events - Ordered within a partition, high throughput (millions of msgs/sec) - Good for: event sourcing, audit logs, real-time analytics pipelines, CDC (change data capture), fan-out to multiple consumer groups Choose RabbitMQ when: task queues, complex routing, transient messages, small/medium scale. Choose Kafka when: event streams, replay, multiple consumers of same data, high throughput, audit trail.

Hints to guide your next attempt

  • Event streaming vs traditional message queue — different guarantees
  • Can consumers re-read messages?

Source tags: message-queue / kafka / rabbitmq / event-streaming / system-design

QUESTION 11 / hard / conceptual

What are the key microservices communication patterns? Circuit breaker, saga, API gateway.

Sample answer

Synchronous communication (REST/gRPC): simple but creates tight coupling. Failure in one service cascades. Circuit Breaker pattern: wrap calls to downstream services. States: - Closed (normal): requests pass through - Open (tripped): circuit breaker returns error immediately without calling the service — prevents cascade failures - Half-open (recovery): let a few requests through to test if service recovered Hystrix, Polly (.NET), Resilience4j implement this. Saga pattern: manage distributed transactions across services without 2PC. - Choreography: services emit events; each service reacts and emits next event. Decentralised, hard to track. - Orchestration: a saga orchestrator tells each service what to do. Centralised, easier to reason. Each step has a compensating transaction for rollback. API Gateway: single entry point for all clients. Handles cross-cutting: auth, rate limiting, SSL termination, request routing, response aggregation. Examples: Kong, AWS API Gateway, NGINX. Service Mesh (Istio, Linkerd): handles mTLS, observability, retry, circuit breaking as infrastructure — no code changes in services.

Hints to guide your next attempt

  • Sync vs async communication
  • How do you handle failures in a chain of services?

Source tags: microservices / circuit-breaker / saga / api-gateway / system-design

QUESTION 12 / medium / system design

Explain the PACELC theorem. How does it extend CAP?

Sample answer

CAP only addresses behavior during a network partition. PACELC says: even when the system is running normally (no partition), there is a tradeoff between Latency (L) and Consistency (C). So the full tradeoff is: if Partition → choose A or C; Else → choose L or C. DynamoDB is PA/EL (available during partition, low latency normally). HBase is PC/EC (consistent always). Most real systems optimize for low latency at the cost of consistency in the normal path.
Read the supplied solution walkthrough

CAP recap

CAP = Consistency, Availability, Partition tolerance. You can only guarantee 2 of 3 during a network split.

The gap CAP ignores

CAP says nothing about normal (non-partition) operation. PACELC fills this gap.

PACELC formula

If Partition: choose A or C. Else: choose L (low latency) or C (strong consistency). Real systems must pick both tradeoffs.

Examples

DynamoDB = PA/EL. Cassandra = PA/EL. HBase = PC/EC. Spanner = PC/EC (uses TrueTime). MongoDB = PA/EC.

Why it matters

When designing, ask: "what latency vs consistency tradeoff is acceptable in the happy path?" — not just during failures.

Source tags: pacelc / cap / consistency / latency / distributed-systems / system-design

Check understanding, not recognition

  • Can you explain the answer without reading it?
  • Can you show when the approach fails or needs a different assumption?
  • Can you connect the concept to a real project, task, or decision you have made?
  • Can you distinguish a simplified interview example from a production requirement?

A LITTLE MORE CLARITY

Frequently asked questions

How many System Design questions are shown here?

This public preview shows 12 questions with the supplied answers from the app's 63-question System Design bank. Full interactive practice requires signing in.

Should I memorize the sample answers?

Use them as reference explanations, not a script or a guarantee of technical correctness for every environment. Explain your assumptions, validate code against your language and version, and discuss trade-offs. Behavioral answers should be built from your own experience.

What do hints and solution steps mean?

Hints identify ideas to consider before reading the answer. When the source question includes steps, they are shown as a separate walkthrough. Example capacities and design targets in a solution are assumptions for that exercise, not real system statistics.

BUILD YOUR NEXT OPPORTUNITY

Practice System Design actively.

Sign in to use the full topic bank and interactive practice workspace.

Open Topic Practice