← Reddit Interview Insights

Reddit·Software Engineer·Onsite - System Design / Architecture·Senior

Senior
May 2026

Summary

System design round at Reddit for a software engineer role, focused entirely on building a notification platform at scale. Pretty deep dive, they wanted the full picture from API contracts down to dead-letter queues.

Questions Asked (5)

Q1

Design a notification system that can deliver messages to users across push, email, SMS, and in-app channels at millions of notifications per minute.

System DesignTechnical Trade-offs
Author's notes

This is the kind of question where you can spiral fast if you don't anchor on requirements first.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and scale, then design a high-level architecture with decoupled components for ingestion, processing, and delivery. Focus on scalability, reliability, and trade-offs, and dive deep into one or two critical areas like fan-out or channel-specific delivery.

Pro tip: Emphasize idempotency and deduplication to handle retries and at-least-once delivery, and discuss how to prioritize notifications (e.g., urgent vs. promotional) to avoid overwhelming users.

1. Clarify Requirements

Ask about notification types, user preferences, delivery guarantees, latency, and scale (e.g., millions per minute). Define functional and non-functional requirements.

2. High-Level Architecture

Propose a decoupled system with an ingestion API, message queue (e.g., Kafka), processing workers, and channel-specific delivery services. Include a user preference service and a template service.

3. Deep Dive into Components

Detail how to handle fan-out (e.g., per-channel queues), rate limiting, retries, and failure handling. Discuss storage for user preferences and notification logs.

4. Scalability and Reliability

Explain how to scale horizontally (partitioning, sharding), ensure high availability (replication, multi-region), and achieve at-least-once delivery with idempotency.

5. Trade-offs and Optimizations

Discuss trade-offs like push vs. pull, synchronous vs. asynchronous, and cost vs. latency. Mention monitoring, alerting, and analytics.

Key Points to Mention

  • Use of message queues (e.g., Kafka) for decoupling and buffering to handle spikes.
  • Channel-specific workers with retry mechanisms and dead-letter queues.
  • User preference management and opt-out handling to comply with regulations.
  • Idempotency keys and deduplication to prevent duplicate notifications.
  • Rate limiting and throttling to protect downstream services and users.
  • Monitoring and metrics for delivery success, latency, and system health.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

How would you design the producer ingest API and the channel adapter interface for a multi-channel notification system?

API & IntegrationsSystem Design
Author's notes

Talked through a REST ingest endpoint with idempotency keys on the producer side, then a common adapter interface that each channel (push, email, SMS) implements.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements: what channels (email, push, SMS, in-app), expected throughput, latency, and reliability needs. Then propose a producer ingest API that accepts notification requests asynchronously with idempotency and validation, and a channel adapter interface that abstracts provider-specific details behind a common contract. Emphasize extensibility, fault tolerance, and observability.

Pro tip: Show you understand the difference between the ingest API (public-facing, high-volume, must be fast and reliable) and the adapter interface (internal, provider-specific, must be pluggable). Mention that you'd version the API and use a schema like CloudEvents for standardization.

1. Clarify Requirements and Constraints

Ask about scale (notifications per second), channels, delivery guarantees, latency, and whether producers need synchronous responses. This shapes the API design and adapter contract.

2. Design the Producer Ingest API

Define a RESTful or gRPC endpoint that accepts a notification request with fields like recipient, template, channel preferences, and metadata. Include idempotency keys, validation, rate limiting, and async processing via a queue.

3. Define the Channel Adapter Interface

Create an interface with methods like send(notification), getStatus(messageId), and validateConfig(). Ensure it's provider-agnostic, supports retries, and allows easy addition of new channels.

4. Address Cross-Cutting Concerns

Discuss error handling, retries with exponential backoff, dead-letter queues, observability (logging, metrics, tracing), and security (auth, PII encryption).

5. Discuss Extensibility and Evolution

Explain how to add new channels without changing the ingest API, versioning strategies, and how to handle provider-specific features via adapter capabilities.

Key Points to Mention

  • Idempotency and exactly-once semantics for ingest API
  • Asynchronous processing with message queues (e.g., Kafka, SQS) for decoupling
  • Adapter interface with common methods and provider-specific implementations
  • Retry policies, circuit breakers, and dead-letter queues for reliability
  • Observability: metrics, logging, and tracing for debugging and monitoring
  • Schema validation and versioning (e.g., using JSON Schema or Protobuf)

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

Walk through how you'd handle deduplication, retries with exponential backoff, and dead-letter queue management in this notification pipeline.

System DesignTechnical Trade-offs
Author's notes

The dedup piece I felt decent about: idempotency keys stored in a fast key-value store, TTL-based expiry.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the pipeline's requirements and constraints, then walk through each component—deduplication, retries with exponential backoff, and DLQ management—in the order events flow. For each, explain the mechanism, trade-offs, and how you'd monitor and handle failures, tying choices back to Reddit's scale and reliability needs.

Pro tip: Emphasize idempotency and observability: deduplication and retries are only safe if downstream consumers are idempotent, and you need metrics and alerts to know when retries or DLQs are spiking. Mention that DLQ messages should be replayable after fixes, not just parked forever.

1. Clarify requirements and constraints

Ask about notification types, volume, latency tolerance, delivery guarantees (at-least-once vs exactly-once), and existing infrastructure. This shows you design for context rather than reciting a generic pattern.

2. Design deduplication

Explain using a unique idempotency key per notification (e.g., event ID + recipient) stored in a fast lookup store like Redis or a database with TTL. Discuss trade-offs: storage cost vs. duplicate prevention window, and how to handle race conditions with atomic checks.

3. Implement retries with exponential backoff

Describe a retry policy with exponential backoff and jitter, capped at a max delay and max attempts. Mention using a message queue with delayed retry (e.g., SQS visibility timeout, RabbitMQ dead-letter exchanges, or a scheduler) and distinguishing transient vs. permanent failures.

4. Manage dead-letter queues

Explain routing messages that exceed retry limits to a DLQ, with metadata (error reason, attempt count, original payload). Cover alerting, manual inspection, and a replay mechanism to reprocess after fixing the root cause.

5. Address monitoring, idempotency, and trade-offs

Highlight metrics (retry rate, DLQ depth, dedup hit rate), idempotent consumers, and trade-offs like at-least-once vs exactly-once, storage costs, and complexity. Tie back to Reddit's scale and user experience.

Key Points to Mention

  • Idempotency keys and idempotent consumers to make retries and deduplication safe
  • Exponential backoff with jitter to avoid thundering herd and retry storms
  • Distinguishing transient vs permanent errors to decide retry vs immediate DLQ
  • DLQ as a replayable buffer with metadata, not a graveyard; include alerting and tooling
  • Observability: metrics, tracing, and alerts for retry rates, DLQ depth, and dedup effectiveness
  • Trade-offs: at-least-once vs exactly-once delivery, storage cost of dedup keys, and complexity of coordination

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

How would you approach rate limiting per notification provider and ensuring you don't overwhelm downstream channels like SMS gateways?

System DesignTechnical Trade-offs
Author's notes

Token bucket per provider, tracked in Redis.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and constraints, then propose a layered rate limiting strategy that combines per-provider quotas, global limits, and adaptive throttling. Emphasize monitoring, backpressure, and graceful degradation to protect downstream SMS gateways and other channels.

Pro tip: Mention that rate limits should be dynamic and based on provider feedback (e.g., error rates, latency) to avoid static limits that either underutilize or overwhelm providers. Also, highlight the importance of idempotency and deduplication to prevent duplicate notifications during retries.

1. Clarify Requirements and Constraints

Ask about scale (notifications per second), provider SLAs, failure modes, and whether limits are per user, per provider, or global. Understand the criticality of different notification types (e.g., urgent vs. marketing).

2. Design a Multi-Layer Rate Limiting Architecture

Propose a combination of client-side throttling, a centralized rate limiter (e.g., token bucket or sliding window) per provider, and a global circuit breaker. Use a distributed cache like Redis for shared state across instances.

3. Implement Adaptive Throttling and Backpressure

Incorporate feedback loops: monitor provider response times, error rates, and queue depths. Dynamically adjust limits and use exponential backoff with jitter for retries. Apply backpressure to upstream producers when queues fill.

4. Ensure Observability and Alerting

Instrument metrics (e.g., rate limit hits, provider latency, error rates) and set up alerts for threshold breaches. Use dashboards to visualize per-provider throughput and saturation.

5. Plan for Failure and Graceful Degradation

Define fallback strategies: queue and retry with delays, downgrade to alternative channels (e.g., email instead of SMS), or drop non-critical notifications. Ensure idempotency to avoid duplicates during retries.

Key Points to Mention

  • Token bucket or sliding window algorithms for rate limiting
  • Distributed rate limiting using Redis or similar for consistency across instances
  • Circuit breaker pattern to prevent cascading failures
  • Adaptive limits based on provider health metrics (error rates, latency)
  • Backpressure mechanisms to slow down producers when downstream is saturated
  • Idempotency and deduplication to handle retries safely

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q5

How would you handle observability for this system, and what metrics or signals would you prioritize?

System DesignProduct Analytics & Metrics
Author's notes

Went with delivery latency per channel, error rates by provider, DLQ depth, and end-to-end notification age.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by framing observability around the system's key user journeys and business goals, then propose a layered approach covering metrics, logs, and traces. Prioritize signals that directly impact user experience and system reliability, such as latency, error rates, and saturation, and tie them to actionable alerts.

Pro tip: Emphasize that observability should be driven by SLOs and error budgets, not just raw metrics. Mention that you'd start with the 'four golden signals' and then add domain-specific metrics like engagement or content freshness for Reddit's use case.

1. Define Observability Goals

Clarify what you want to achieve: reduce MTTD/MTTR, ensure SLOs, and understand user impact. Align with business metrics like daily active users or content freshness.

2. Choose the Right Signals

Select metrics (e.g., latency, traffic, errors, saturation), logs (structured, with context), and traces (distributed tracing for critical paths). Prioritize based on user impact and system criticality.

3. Implement Instrumentation

Use standard tools (Prometheus, OpenTelemetry, etc.) to collect data. Ensure high cardinality and context are captured without overwhelming storage or cost.

4. Set Up Alerting and Dashboards

Create actionable alerts based on SLOs and error budgets. Build dashboards for different audiences: on-call engineers, product managers, and executives.

5. Iterate and Improve

Continuously review incidents and adjust metrics and alerts. Use post-mortems to identify missing signals and refine observability coverage.

Key Points to Mention

  • The four golden signals: latency, traffic, errors, and saturation.
  • SLOs and error budgets to prioritize what to monitor and alert on.
  • Distributed tracing to understand request flow and bottlenecks in microservices.
  • Structured logging with correlation IDs for efficient debugging.
  • Business-level metrics like user engagement, content freshness, and vote counts.
  • Cost management: sampling traces and aggregating metrics to control observability expenses.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.