← J.P. Morgan Interview Insights

J.P. Morgan·Software Engineer·Onsite - System Design / Architecture·Senior

SeniorPrefer not to say
Jul 2026

Summary

System design round at J.P. Morgan for a software engineer role, focused entirely on designing a large-scale notification platform. The interview went deep on queues, rate limiting, and reliability mechanics across multiple delivery channels.

Questions Asked (8)

Q1

Design a scalable notification service that lets internal teams send messages across push, email, and SMS via a single API call. How do you architect the send path and keep channels pluggable?

System DesignAPI & IntegrationsTechnical Trade-offs
Author's notes

This is the core question and it's bigger than it sounds.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements (scale, latency, delivery guarantees, compliance) and then present a high-level architecture with a unified API, a message queue for decoupling, and a pluggable channel abstraction. Emphasize scalability, reliability, and extensibility, and discuss trade-offs like synchronous vs asynchronous processing and at-least-once vs exactly-once delivery.

Pro tip: In regulated environments like J.P. Morgan, highlight auditability, data privacy (PII handling), and idempotency from the start—these are often as important as scalability.

1. Clarify Requirements and Constraints

Ask about expected volume, latency SLAs, delivery guarantees, compliance needs (e.g., GDPR, PCI), and supported channels. This ensures your design addresses the right priorities.

2. Design the Unified API and Ingestion Layer

Define a single API endpoint that accepts a standard payload (recipient, message, channel preferences, metadata). Use an API gateway for authentication, rate limiting, and validation before passing to the core service.

3. Architect the Send Path with Asynchronous Processing

Decouple ingestion from delivery using a message queue (e.g., Kafka, RabbitMQ) to handle bursts and enable retries. A dispatcher service routes messages to channel-specific workers based on the requested channel.

4. Implement Pluggable Channel Adapters

Define a common interface (e.g., send, validate, getStatus) that each channel adapter implements. Use a registry or factory pattern to dynamically load adapters, making it easy to add new channels without changing core logic.

5. Address Scalability, Reliability, and Observability

Scale horizontally by adding workers; use idempotency keys to avoid duplicate sends; implement retries with exponential backoff and dead-letter queues. Add monitoring, logging, and tracing for end-to-end visibility.

Key Points to Mention

  • Asynchronous processing with message queues for decoupling and scalability
  • Channel abstraction via interface and adapter pattern for pluggability
  • Idempotency and deduplication to handle retries safely
  • Rate limiting and backpressure to protect downstream providers
  • Observability: metrics, logging, and distributed tracing
  • Compliance and security: encryption, PII redaction, audit logs

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

Q2

What clarifying questions would you ask before diving into the design? Things like delivery guarantees, user preferences, latency targets, and compliance constraints.

System DesignAdaptability & Ambiguity
Author's notes

I asked about delivery guarantees and latency right away, which landed well.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Demonstrate a structured approach to requirements gathering by categorizing questions into functional, non-functional, and constraint-based areas. Emphasize the importance of clarifying these aspects before design to avoid costly rework and ensure alignment with business and regulatory needs.

Pro tip: In a financial institution like J.P. Morgan, always ask about compliance and data sensitivity early, as they can fundamentally shape the architecture. Also, tie latency and delivery guarantees to business impact to show you understand the domain.

1. Clarify Functional Requirements

Ask about core features, user roles, and primary use cases to understand what the system must do. For example: 'What are the key user journeys?' or 'What operations must be supported?'

2. Define Non-Functional Requirements

Inquire about performance, scalability, availability, and latency targets. For instance: 'What are the expected request rates and response time SLAs?' or 'What is the acceptable downtime?'

3. Identify Constraints and Compliance

Ask about regulatory requirements, data residency, security standards, and budget constraints. For example: 'Are there specific compliance regulations like GDPR, PCI-DSS, or SOX?' or 'What are the data retention policies?'

4. Understand Data and Delivery Guarantees

Probe into data consistency needs, delivery semantics (at-least-once, exactly-once), and user preferences. For example: 'Is eventual consistency acceptable?' or 'What are the data loss tolerances?'

5. Prioritize and Validate Assumptions

Summarize your understanding and confirm priorities with the interviewer. Ask: 'Which of these is most critical?' to ensure you focus on what matters most.

Key Points to Mention

  • Delivery guarantees: at-least-once, at-most-once, exactly-once semantics and their trade-offs.
  • Latency targets: p99 latency, throughput requirements, and how they impact architecture choices.
  • User preferences: consistency vs. availability, read vs. write heavy patterns, and client types.
  • Compliance constraints: GDPR, PCI-DSS, SOX, data residency, audit trails, and encryption.
  • Scalability and availability: expected growth, SLA, disaster recovery, and fault tolerance.
  • Cost and resource constraints: budget, existing infrastructure, and operational overhead.

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

Q3

Why are message queues essential in this architecture, and how do you use them to handle bursts, retries, and provider outages?

System DesignTechnical Trade-offs
Author's notes

Went with separate high-priority and bulk topics so OTPs don't get stuck behind a marketing blast.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by defining the role of message queues as a decoupling and buffering layer in distributed systems, then systematically address bursts, retries, and provider outages with concrete mechanisms like backpressure, dead-letter queues, and circuit breakers. Emphasize trade-offs such as added complexity and latency, and tie your answer to reliability and scalability goals relevant to financial systems.

Pro tip: Quantify the impact: mention how queues absorb traffic spikes (e.g., 10x burst) and reduce provider outage blast radius, showing you think in terms of SLAs and customer impact. Also, highlight idempotency and exactly-once semantics as critical for financial transactions.

1. Explain why queues are essential

Describe how message queues decouple producers and consumers, enable asynchronous processing, and provide buffering to smooth traffic spikes. Mention that in a financial architecture, this ensures reliability and fault tolerance.

2. Handle bursts with buffering and backpressure

Explain that queues absorb sudden load increases by storing messages until consumers can process them. Discuss backpressure mechanisms to prevent overload and auto-scaling consumers based on queue depth.

3. Implement retries with exponential backoff and DLQs

Detail how to retry failed messages with exponential backoff and jitter to avoid thundering herd. After max retries, move messages to a dead-letter queue for manual inspection and alerting.

4. Mitigate provider outages with circuit breakers and fallbacks

Describe using circuit breakers to stop sending to a failing provider, and fallback strategies like routing to alternate providers or queuing for later. Ensure idempotency to handle duplicate deliveries.

5. Discuss trade-offs and monitoring

Acknowledge trade-offs: increased complexity, potential latency, and need for idempotent consumers. Emphasize monitoring queue depth, consumer lag, and error rates to ensure system health.

Key Points to Mention

  • Decoupling and asynchronous communication
  • Buffering to absorb bursts and backpressure
  • Retry policies with exponential backoff and jitter
  • Dead-letter queues for poison messages
  • Circuit breakers and fallback mechanisms for provider outages
  • Idempotency and exactly-once processing semantics

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

Q4

How do you implement rate limiting at multiple layers: protecting downstream providers, preventing notification spam to users, and guarding against abusive internal callers?

System DesignAPI & Integrations
Author's notes

Three distinct layers and I only covered two cleanly.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Structure your answer by identifying the three distinct rate-limiting layers (downstream providers, user notifications, internal callers) and explain how each requires different algorithms, storage, and enforcement points. Emphasize a defense-in-depth strategy where each layer has independent limits and fallback mechanisms to prevent cascading failures.

Pro tip: Mention that rate limiting should be observable and configurable at runtime—use feature flags and metrics to adjust limits without redeploying, which is critical in regulated environments like J.P. Morgan where sudden traffic spikes or policy changes occur.

1. Clarify requirements and constraints

Ask about expected traffic patterns, latency budgets, and compliance requirements (e.g., fair access, audit trails). This shows you understand that rate limiting is not one-size-fits-all.

2. Design for downstream provider protection

Use client-side rate limiters (e.g., token bucket) per provider, with circuit breakers and fallbacks. Store counters in a distributed cache like Redis with TTL to avoid overloading the provider.

3. Prevent notification spam to users

Implement per-user and per-channel limits (e.g., sliding window) at the notification service layer. Deduplicate messages and allow user preferences to override defaults, ensuring critical alerts bypass limits.

4. Guard against abusive internal callers

Apply rate limits at the API gateway or service mesh level using caller identity (e.g., API keys, mTLS). Use quotas per team or service, and enforce with a centralized policy engine.

5. Ensure observability and adaptability

Instrument metrics (e.g., 429 responses, limit hits) and set up alerts. Use dynamic configuration to adjust limits in real-time based on load or business needs.

Key Points to Mention

  • Token bucket vs. sliding window vs. fixed window algorithms and their trade-offs
  • Distributed rate limiting using Redis or a dedicated service (e.g., Envoy, Kong)
  • Circuit breakers and bulkheads to isolate failures and prevent retry storms
  • User-level vs. global limits for notifications, with priority queues for critical messages
  • Authentication and authorization for internal callers, with per-caller quotas
  • Monitoring, alerting, and dynamic configuration to adapt to changing conditions

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

Q5

An SMS provider goes down for 30 minutes. Walk through exactly what happens to in-flight and queued SMS notifications, and how the system recovers without losing or duplicating messages.

System DesignTechnical Trade-offsRoot Cause Analysis
Author's notes

This follow-up tripped me up more than I expected.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Structure your answer around the message lifecycle: how in-flight and queued messages are handled during the outage, how the system detects recovery, and how it resumes processing with idempotency and retries to avoid loss or duplication. Emphasize trade-offs between consistency, availability, and latency, and mention monitoring and alerting for root cause analysis.

Pro tip: Show you understand that exactly-once delivery is impossible in distributed systems; instead, aim for at-least-once delivery with idempotent consumers to achieve effectively-once processing. Also, mention that you'd design for graceful degradation, such as falling back to a secondary provider or queueing messages for later delivery.

1. Detect and Isolate the Failure

Explain how the system detects the provider outage (e.g., via health checks, error rates, timeouts) and immediately stops sending new messages to the failed provider to prevent further failures.

2. Handle In-Flight Messages

Describe what happens to messages already sent to the provider but not yet acknowledged: they may be lost or delayed. Implement timeouts and retries with idempotency keys to avoid duplicates when retrying.

3. Manage Queued Messages

Explain that queued messages are held in a durable queue (e.g., Kafka, SQS) and are not lost. The system should pause consumption or route to a fallback provider if available, ensuring messages remain safe.

4. Recover and Resume Processing

Once the provider recovers, the system should gradually resume sending, starting with a canary or rate-limited approach to avoid overwhelming the provider. Use exponential backoff and circuit breakers.

5. Ensure No Loss or Duplication

Implement idempotent message processing on the consumer side (e.g., using unique message IDs) and deduplication logic. Monitor for duplicates and reconcile with provider logs if possible.

Key Points to Mention

  • Idempotency keys and deduplication to prevent duplicate messages
  • Durable queues and persistent storage to avoid message loss
  • Retry policies with exponential backoff and jitter
  • Circuit breakers and fallback providers for graceful degradation
  • Monitoring, alerting, and logging for root cause analysis
  • Trade-offs between consistency, availability, and latency (CAP theorem)

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

Q6

How do you guarantee a one-time passcode gets delivered within seconds even when a large marketing blast is running on the same platform?

System DesignTechnical Trade-offs
Author's notes

Separate priority queues with dedicated consumer pools that don't share capacity with bulk workers.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the requirements: OTP delivery within seconds (e.g., <5s) and the scale of the marketing blast. Then propose a multi-layered architecture that isolates OTP traffic from bulk marketing traffic, using dedicated queues, priority lanes, and autoscaling to guarantee low latency. Finally, discuss trade-offs like cost, complexity, and the need for monitoring and fallbacks.

Pro tip: Emphasize the importance of measuring and monitoring end-to-end latency with percentiles (p99) and having a fallback mechanism (e.g., SMS failover to voice) to meet strict SLAs. This shows you think about reliability beyond just the happy path.

1. Clarify requirements and constraints

Ask about expected OTP volume, marketing blast size, acceptable latency, and existing infrastructure. This ensures your solution is tailored to the actual scale and SLAs.

2. Isolate OTP traffic from marketing traffic

Propose separate queues, topics, or even separate service instances for OTP and marketing. This prevents marketing blasts from starving OTP messages.

3. Prioritize and autoscale OTP processing

Implement priority queues and autoscaling for OTP workers based on queue depth and latency. Use dedicated resources or reserved capacity to guarantee performance.

4. Optimize the delivery path

Use direct connections to SMS/email providers, connection pooling, and pre-warmed connections. Consider edge computing or regional endpoints to reduce network latency.

5. Monitor, test, and plan for failures

Set up real-time monitoring with alerts on latency and error rates. Conduct load tests simulating marketing blasts. Have fallback providers and retry logic with exponential backoff.

Key Points to Mention

  • Traffic isolation: separate queues, topics, or clusters for OTP vs. marketing.
  • Priority queuing and dedicated worker pools for OTP messages.
  • Autoscaling based on queue depth and latency metrics.
  • Direct integration with providers and connection reuse to minimize latency.
  • End-to-end monitoring with p99 latency and alerting.
  • Fallback mechanisms (e.g., alternate provider, voice call) and graceful degradation.

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

Q7

Compare Kafka and RabbitMQ for this use case. Which would you pick for bulk fan-out and which for transactional notifications?

System DesignTechnical Trade-offs
Author's notes

Kafka for bulk because of retention, replay, and partitioned consumer scaling.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the two use cases: bulk fan-out (high-throughput, multiple consumers, order not critical) and transactional notifications (low-latency, exactly-once, ordered per transaction). Then compare Kafka and RabbitMQ on throughput, delivery guarantees, ordering, and operational complexity, and finally recommend the best fit for each use case with trade-offs.

Pro tip: In financial systems like J.P. Morgan, transactional notifications often require strict ordering and exactly-once semantics, so RabbitMQ with publisher confirms and manual acks is a safer choice, while Kafka excels at high-volume fan-out with its partitioned log and consumer groups. Always mention the need for idempotency and dead-letter queues to handle failures gracefully.

1. Clarify use cases

Define bulk fan-out as high-throughput distribution to many consumers where order may not be critical, and transactional notifications as low-latency, ordered, exactly-once delivery per transaction.

2. Compare key dimensions

Evaluate Kafka and RabbitMQ on throughput, latency, delivery guarantees, ordering, scalability, and operational complexity.

3. Match to use cases

Recommend Kafka for bulk fan-out due to its partitioned log and consumer groups, and RabbitMQ for transactional notifications due to its flexible routing and strong delivery guarantees.

4. Address trade-offs and mitigations

Discuss potential drawbacks (e.g., Kafka's at-least-once default, RabbitMQ's scaling limits) and how to mitigate them (idempotent consumers, clustering, dead-letter queues).

5. Conclude with a clear recommendation

Summarize your choice for each use case, emphasizing alignment with business requirements like reliability and compliance.

Key Points to Mention

  • Kafka's high throughput and horizontal scalability via partitions and consumer groups
  • RabbitMQ's support for complex routing, message priorities, and per-message acknowledgment
  • Delivery semantics: Kafka's at-least-once vs. RabbitMQ's exactly-once with transactions
  • Ordering guarantees: Kafka's per-partition order vs. RabbitMQ's per-queue order
  • Operational considerations: Kafka's need for ZooKeeper/KRaft and tuning vs. RabbitMQ's ease of setup
  • Financial industry requirements: auditability, idempotency, and dead-letter queues for compliance

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

Q8

How would you add delivery status tracking and an in-app inbox on top of this send-focused design?

System DesignData Modeling
Author's notes

Short answer: provider webhooks write status events back into a separate topic, consumers update a delivery status store, and the inbox is just a read model built from those events.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by acknowledging the existing send-focused design and its limitations, then propose extending it with a delivery status tracking service and an in-app inbox. Focus on data modeling for status updates and inbox items, and discuss how to handle real-time updates and scalability.

Pro tip: Emphasize idempotency and eventual consistency in status tracking, as financial systems require reliability and auditability. Also, consider how to handle read/unread states and pagination for the inbox to ensure performance.

1. Clarify Requirements and Scope

Ask clarifying questions about expected delivery statuses (e.g., sent, delivered, read), inbox features (e.g., filtering, archiving), and non-functional requirements like latency and throughput.

2. Design Data Models

Propose schemas for delivery status events (e.g., message_id, status, timestamp, metadata) and inbox items (e.g., user_id, message_id, read_status, timestamp). Consider using a time-series or append-only store for status history.

3. Architect the Tracking Service

Outline a service that consumes delivery events from the send pipeline, updates status in a database, and publishes updates to subscribers (e.g., via WebSockets or push notifications). Ensure idempotency and ordering.

4. Design the In-App Inbox

Describe how to aggregate messages per user, support pagination, and manage read/unread states. Discuss caching strategies and how to sync with the tracking service for real-time updates.

5. Address Scalability and Reliability

Discuss partitioning strategies (e.g., by user_id), handling high write volumes, and ensuring data consistency. Mention monitoring, alerting, and fallback mechanisms.

Key Points to Mention

  • Event-driven architecture for status updates (e.g., Kafka, message queues)
  • Data modeling: append-only status log vs. current state table
  • Idempotency and deduplication of status events
  • Real-time updates via WebSockets or server-sent events
  • Pagination and indexing for inbox queries
  • Read/unread state management and synchronization
  • Scalability considerations: sharding by user, caching, and eventual consistency

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