← DoorDash Interview Insights

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

SeniorPrefer not to say
Apr 2026

Summary

DoorDash system design round focused entirely on building a resilient bootstrap API that aggregates three downstream services into one response for a client's first paint. The problem sounds manageable until you realize the dependency chain forces a sequential step before you can parallelize anything, and partial failure handling is where they really dig in.

Questions Asked (10)

Q1

Design a bootstrap API endpoint that fans out to three internal services and returns a single aggregated response for a client app's first screen load.

System DesignAPI & Integrations
Author's notes

The core of the whole interview.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements: what data is needed for the first screen, latency and consistency expectations, and failure modes. Then design a BFF (Backend for Frontend) endpoint that concurrently calls the three services, aggregates and transforms the responses, and handles partial failures gracefully with caching and timeouts.

Pro tip: Emphasize that the endpoint should be resilient: use timeouts, circuit breakers, and fallbacks for each downstream call, and consider returning partial data with a 200 status if some services fail, rather than failing the entire request.

1. Clarify requirements and constraints

Ask about the data needed for the first screen, acceptable latency, consistency requirements, and expected traffic patterns. This ensures the design meets the actual needs.

2. Design the API contract

Define the endpoint path, HTTP method, request parameters, and response schema. Consider versioning and how to represent partial failures in the response.

3. Implement fan-out and aggregation

Use concurrent calls (e.g., with a thread pool or async I/O) to the three services. Aggregate the results, transform them into the client-friendly format, and handle timeouts and errors per service.

4. Add resilience and performance optimizations

Incorporate caching, circuit breakers, retries with backoff, and fallbacks. Consider using a BFF pattern to tailor the response for the client.

5. Discuss monitoring and trade-offs

Explain how to monitor latency, error rates, and downstream health. Discuss trade-offs between consistency, availability, and latency.

Key Points to Mention

  • Concurrency: use parallel calls to reduce latency (e.g., CompletableFuture, asyncio, goroutines).
  • Partial failure handling: return partial data with appropriate status codes and error details.
  • Caching: cache aggregated responses or individual service responses to reduce load and improve latency.
  • Timeouts and circuit breakers: prevent cascading failures and ensure fast fallbacks.
  • BFF pattern: tailor the API for the client's first screen, avoiding over-fetching.
  • Observability: log and monitor each downstream call, aggregation time, and error rates.

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

Q2

How do you define the API contract so a client can distinguish between a section being genuinely empty versus a section that failed to load?

API & IntegrationsTechnical Trade-offs
Author's notes

Blanked for a second here.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by framing the problem as a need for explicit state representation in the API contract, not just data presence. Propose a design where each section includes a status field (e.g., 'loaded', 'empty', 'error') alongside optional data, and discuss how this scales across different endpoints. Emphasize trade-offs between simplicity and clarity, and how this improves client-side error handling and user experience.

Pro tip: Mention that this pattern is common in GraphQL with union types or in REST with a 'status' envelope, and that it aligns with DoorDash's need for reliable, real-time data in a high-scale environment. Also, note that you'd document this contract clearly and consider versioning to avoid breaking changes.

1. Clarify the problem and requirements

Restate the question to ensure understanding: clients need to differentiate between empty and failed sections. Discuss why this matters (e.g., UI behavior, retries, user trust) and any constraints (e.g., backward compatibility, performance).

2. Propose a contract design

Suggest including a status field per section (e.g., 'status': 'success' | 'empty' | 'error') and optional data or error details. Explain how this makes states explicit and machine-readable.

3. Discuss implementation and trade-offs

Cover how to implement this in REST (e.g., HTTP status codes per section? probably not; use envelope) or GraphQL (union types). Mention trade-offs: added complexity vs. clarity, payload size, and client handling.

4. Address edge cases and scalability

Talk about partial failures, timeouts, and how to handle nested sections. Consider versioning and documentation to ensure clients can rely on the contract.

5. Conclude with impact

Summarize how this improves client-side logic, user experience, and debugging. Tie back to DoorDash's context of high reliability and real-time updates.

Key Points to Mention

  • Explicit status field per section (e.g., 'status': 'success' | 'empty' | 'error')
  • Optional data field that is present only when status is 'success'
  • Error details for failed sections (e.g., error code, message)
  • Trade-offs: increased payload size vs. improved clarity and client handling
  • GraphQL union types or REST envelope patterns as implementation options
  • Versioning and documentation to maintain backward compatibility

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

Q3

What HTTP status code does your bootstrap endpoint return when some downstream data is available but one or more sections failed?

API & IntegrationsTechnical Trade-offs
Author's notes

Went with 207 multi-status initially, then second-guessed myself and said maybe just 200 with error detail in the body.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the semantics of the bootstrap endpoint: it's a composite response aggregating multiple downstream sections. Explain that the appropriate status code depends on whether the partial failure is expected and how the client should handle it, then recommend a specific code (e.g., 200 with a partial success payload, or 207 Multi-Status) and justify it with trade-offs.

Pro tip: Mention that DoorDash's mobile clients often prefer a 200 with a structured 'partial' flag to avoid triggering generic error handling, but if the endpoint is used by external partners, 207 or 206 may be more semantically correct. Always align with your API contract and client capabilities.

1. Clarify the endpoint's contract

Determine whether the bootstrap endpoint is internal (mobile app) or external (partner API), and whether clients are designed to handle partial data. This drives the choice of status code.

2. Evaluate status code options

Consider 200 OK (with a partial success body), 207 Multi-Status, 206 Partial Content, or 503 Service Unavailable. Weigh semantic correctness against client behavior and error handling.

3. Choose based on client and business needs

If clients can gracefully degrade, 200 with a clear payload is often best. If strict HTTP semantics matter, 207 is appropriate. Avoid 5xx unless the entire response is unusable.

4. Define the response body structure

Include a top-level status, per-section statuses, and any partial data. This gives clients the information to render what's available and retry failed sections.

5. Justify with trade-offs

Explain why your choice balances developer experience, observability, and correctness. Mention monitoring and alerting on partial failures to avoid silent degradation.

Key Points to Mention

  • HTTP status code semantics: 200 vs 207 vs 206 vs 5xx
  • Client-side error handling and graceful degradation
  • API contract and backward compatibility
  • Observability: logging and alerting on partial failures
  • Trade-offs between strict HTTP compliance and practical client behavior
  • DoorDash's mobile-first context and potential use of feature flags or fallbacks

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

Q4

Walk through how you sequence and parallelize the three downstream calls, and how you keep total latency within budget.

System DesignTechnical Trade-offs
Author's notes

This part went well.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the latency budget and the dependencies between the three calls, then propose a hybrid sequencing strategy that parallelizes independent calls and sequences dependent ones. Explain how you would use timeouts, fallbacks, and caching to stay within budget, and quantify the expected latency with a simple timeline.

Pro tip: Mention that you would set the overall timeout to slightly less than the budget and use a 'hedged request' pattern for the most critical call to reduce tail latency, showing you think about p99, not just average.

1. Clarify requirements and dependencies

Ask about the latency budget, the expected p50/p99 latency of each call, and whether the calls are independent or have data dependencies. This ensures your design targets the right constraints.

2. Design the execution plan

If calls are independent, run them in parallel with a single timeout; if dependent, sequence them but overlap any independent portions. Use a coordinator (e.g., CompletableFuture, Promise.all) to manage the flow.

3. Apply latency reduction techniques

Introduce caching for repeated data, use hedged requests for critical calls, and set per-call timeouts that sum to less than the budget. Consider circuit breakers to avoid cascading delays.

4. Validate against budget and iterate

Walk through a timeline showing expected latency, including worst-case scenarios. If the budget is exceeded, propose trade-offs like degrading non-critical calls or using stale cache.

Key Points to Mention

  • Latency budget breakdown and p99 vs p50 considerations
  • Parallelization with CompletableFuture/Promise.all and thread pool sizing
  • Timeouts, retries with exponential backoff, and circuit breakers
  • Caching strategies (local, distributed) and cache invalidation
  • Fallback mechanisms (default values, degraded responses) to meet budget
  • Monitoring and alerting on latency to detect regressions

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

Q5

How do you make the endpoint resilient to slow or failing downstream services? Walk through your reliability stack.

System DesignTechnical Trade-offs
Author's notes

Covered timeouts first since they're basically free, then retries with jitter (safe here since it's all GET), then circuit breakers per downstream so one sick service doesn't cause everyone else to queue up waiting on timeouts.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Structure your answer as a layered reliability stack, starting from the client and moving inward to the downstream service. For each layer, explain the technique, its purpose, and the trade-offs involved, tying it back to DoorDash's high-throughput, low-latency environment.

Pro tip: Emphasize that resilience is about graceful degradation, not just preventing failures—show how you prioritize user experience by falling back to cached or default data when downstreams are slow or down.

1. Set aggressive timeouts and retries

Explain how you configure timeouts to fail fast and use retries with exponential backoff and jitter to handle transient failures without overwhelming the downstream.

2. Implement circuit breakers and bulkheads

Describe how circuit breakers trip after repeated failures to prevent cascading failures, and how bulkheads isolate resources so one slow downstream doesn't exhaust all threads or connections.

3. Add fallbacks and caching

Discuss serving stale or default data from a cache, or using a degraded response, to maintain functionality when the downstream is unavailable.

4. Monitor, alert, and load shed

Explain how you track metrics like latency and error rates, set up alerts, and implement load shedding or rate limiting to protect the system under extreme load.

5. Test and iterate

Mention chaos engineering and load testing to validate resilience, and how you use post-mortems to continuously improve the reliability stack.

Key Points to Mention

  • Timeouts, retries with exponential backoff and jitter
  • Circuit breakers (e.g., Hystrix, Resilience4j) and bulkhead patterns
  • Fallback strategies: cached responses, default values, degraded features
  • Monitoring and observability: metrics, tracing, logging, alerting
  • Load shedding, rate limiting, and backpressure
  • Trade-offs: consistency vs availability, latency vs reliability, cost of redundancy

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

Q6

What is your caching strategy for the bootstrap response, and are there any sections you would not cache?

Technical Trade-offsSystem Design
Author's notes

Said I'd cache profile and address data with longer TTLs since they change infrequently, but I was more cautious about payment methods.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying what the bootstrap response contains and its role in app startup, then propose a layered caching strategy (client, CDN, server) with appropriate TTLs and invalidation. Explicitly call out sections that should not be cached due to personalization, real-time data, or security concerns, and justify your choices with trade-offs.

Pro tip: Emphasize that caching is not just about performance but also about correctness and user experience—show you understand the cost of stale data and how to balance it with freshness. Mention that you would instrument cache hit/miss rates and monitor for anomalies to continuously validate the strategy.

1. Clarify the bootstrap response

Define what data the bootstrap response includes (e.g., user profile, feature flags, config, store listings) and its criticality for app startup. This sets the context for caching decisions.

2. Propose a multi-layer caching strategy

Outline caching at different layers: client-side (memory/disk), CDN edge, and server-side (Redis/Memcached). Specify TTLs based on data volatility and invalidation mechanisms (e.g., versioning, pub/sub).

3. Identify non-cacheable sections

List sections that should not be cached: personalized user data, real-time inventory/availability, sensitive information, and rapidly changing promotions. Explain why caching them risks staleness or security issues.

4. Discuss trade-offs and fallbacks

Acknowledge trade-offs between freshness and performance, and describe fallback strategies (e.g., stale-while-revalidate, graceful degradation) if cache fails or data is stale.

5. Mention monitoring and iteration

Explain how you would monitor cache effectiveness (hit rate, latency, error rates) and iterate on TTLs and invalidation rules based on metrics and user feedback.

Key Points to Mention

  • TTL and invalidation strategies (e.g., time-based, event-driven, versioned keys)
  • Layered caching: client, CDN, server-side caches
  • Personalization and user-specific data should not be cached or must be cached per-user with short TTL
  • Real-time data (e.g., store hours, delivery availability) requires short TTL or no caching
  • Security and privacy considerations (e.g., PII, auth tokens)
  • Monitoring and metrics to validate cache performance and correctness

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

Q7

How do you instrument and alert on failures in this system if partial failures are designed not to surface as HTTP 5xx errors?

System DesignProduct Analytics & Metrics
Author's notes

Good follow-up that I wasn't fully prepared for.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Acknowledge that partial failures require observability beyond HTTP status codes, focusing on business-level metrics, distributed tracing, and structured logging. Describe a layered monitoring strategy that correlates signals across services to detect and alert on degraded states.

Pro tip: Emphasize that alerting should be based on user-impacting symptoms (e.g., order failure rate) rather than raw technical metrics, and use techniques like canary analysis and synthetic transactions to catch silent failures.

1. Define business and functional SLIs

Identify key user journeys (e.g., order placement, payment) and define service level indicators (SLIs) that reflect success, such as order completion rate or payment success rate. These SLIs should capture partial failures even when HTTP responses are 2xx.

2. Instrument with structured logging and tracing

Emit structured logs with correlation IDs and use distributed tracing to follow requests across services. This allows detection of failures in downstream calls that might be swallowed and not propagated as HTTP errors.

3. Aggregate metrics and set SLOs

Collect metrics on SLIs (e.g., via Prometheus) and define service level objectives (SLOs) with error budgets. Monitor burn rates to alert on deviations from expected success rates.

4. Implement multi-layered alerting

Set up alerts on SLO violations, anomaly detection on business metrics, and synthetic canary tests that simulate critical user flows. Use alerting thresholds that balance sensitivity and noise.

5. Iterate and refine with feedback loops

Continuously review alerts and incidents to adjust SLIs, thresholds, and instrumentation. Incorporate post-mortems to improve detection of silent failures.

Key Points to Mention

  • Business-level metrics (e.g., order success rate) as primary indicators
  • Distributed tracing and correlation IDs to track requests across services
  • Structured logging with error context for partial failures
  • SLOs and error budgets to quantify acceptable failure rates
  • Synthetic monitoring and canary tests to simulate user flows
  • Alerting on symptoms (user impact) rather than causes (e.g., CPU)

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

Q8

The endpoint takes a user_id as a query parameter. What is the authorization risk and how would you address it?

API & IntegrationsTechnical Trade-offs
Author's notes

Caught me a bit off guard as a follow-up.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Identify the vulnerability as an Insecure Direct Object Reference (IDOR) or Broken Object Level Authorization (BOLA), where a user can manipulate the user_id to access another user's data. Then, propose a robust authorization strategy that validates the authenticated user's identity and permissions against the requested resource, rather than trusting client-supplied parameters.

Pro tip: Emphasize that authorization must be enforced server-side on every request, and mention that using opaque identifiers (like UUIDs) can add a layer of defense but is not a substitute for proper access control.

1. Identify the Risk

Explain that the endpoint is vulnerable to IDOR/BOLA because it relies on a user-supplied user_id without verifying that the authenticated user is authorized to access that resource.

2. Assess Impact

Describe the potential consequences: unauthorized data exposure, privacy breaches, and compliance violations (e.g., GDPR, CCPA).

3. Propose Mitigation

Recommend implementing server-side authorization checks that compare the authenticated user's ID (from the session/token) with the requested user_id, and deny access if they don't match or if the user lacks permission.

4. Consider Additional Layers

Suggest using indirect references (e.g., UUIDs) to make guessing harder, and implementing centralized authorization logic (e.g., middleware) to avoid inconsistencies.

5. Validate and Monitor

Mention the importance of logging access attempts, monitoring for anomalies, and conducting regular security audits to ensure the fix remains effective.

Key Points to Mention

  • IDOR (Insecure Direct Object Reference) or BOLA (Broken Object Level Authorization)
  • Server-side authorization checks using the authenticated user's identity
  • Principle of least privilege: users should only access their own resources
  • Use of opaque identifiers (UUIDs) to prevent enumeration
  • Centralized authorization middleware to enforce policies consistently
  • Logging and monitoring for unauthorized access attempts

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

Q9

How does your design change at 100x the current read volume, and what breaks first?

System DesignTechnical Trade-offs
Author's notes

Said the user service becomes the bottleneck since it's on the critical path for every single request.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the current architecture and read volume, then systematically scale each component to 100x, identifying bottlenecks and failure points. Prioritize read-heavy optimizations like caching, replication, and denormalization, and explain what breaks first (e.g., database connections, cache misses, network bandwidth).

Pro tip: Quantify the impact: estimate current QPS, then calculate 100x and show how each layer handles it. Mention that the first thing to break is often the database's connection pool or the cache's eviction rate, and propose specific mitigations like read replicas or sharding.

1. Clarify Current State

Ask about current read volume, data size, and architecture to establish a baseline. Confirm assumptions about consistency, latency, and budget constraints.

2. Identify Scaling Levers

List read-scaling techniques: caching (client, CDN, application, database), read replicas, denormalization, and sharding. Explain how each applies to the system.

3. Predict Bottlenecks

Analyze each component (load balancer, app servers, cache, database) to determine what fails first at 100x. Consider connection limits, CPU, memory, network I/O, and storage throughput.

4. Propose Mitigations

For each bottleneck, suggest concrete solutions (e.g., increase cache hit rate, add replicas, use read-only endpoints, implement backpressure). Prioritize by impact and effort.

5. Validate and Iterate

Discuss how to test the scaled design (load testing, monitoring) and what metrics to watch. Mention trade-offs like cost, complexity, and consistency.

Key Points to Mention

  • Caching strategies (e.g., Redis, Memcached, CDN) and cache invalidation
  • Database read replicas and eventual consistency trade-offs
  • Sharding or partitioning strategies for horizontal scaling
  • Connection pooling and database max connections
  • Denormalization and precomputed views for read-heavy workloads
  • Monitoring and metrics to detect bottlenecks (e.g., QPS, latency, cache hit rate)

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

Q10

After a circuit breaker closes following an outage, how do you prevent a thundering herd from overwhelming the recovering downstream service?

System DesignAdaptability & Ambiguity
Author's notes

Half-circuit state with a small probe traffic percentage, then gradually increase.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by acknowledging the thundering herd problem and its impact on a recovering service. Then, outline a multi-layered strategy combining client-side backoff with jitter, server-side load shedding, and gradual traffic ramp-up. Finally, emphasize the importance of monitoring and adaptive control to ensure stability.

Pro tip: Mention that you would implement a circuit breaker with a half-open state that allows a limited number of probe requests, and use randomized exponential backoff to spread out retries. This shows you understand both the pattern and the practical implementation details.

1. Acknowledge the problem

Briefly explain what a thundering herd is and why it occurs after a circuit breaker closes, highlighting the risk of overwhelming the downstream service.

2. Client-side mitigation

Describe techniques like exponential backoff with jitter, request queuing, and rate limiting on the client side to spread out retries and reduce burstiness.

3. Server-side protection

Discuss server-side strategies such as load shedding, request throttling, and graceful degradation to handle excess load during recovery.

4. Gradual traffic ramp-up

Explain how to gradually increase traffic using canary releases, weighted routing, or a token bucket algorithm to allow the service to warm up.

5. Monitoring and adaptation

Emphasize the need for real-time monitoring of key metrics (latency, error rates, queue depths) and adaptive control loops to adjust traffic based on service health.

Key Points to Mention

  • Exponential backoff with jitter to avoid synchronized retries
  • Circuit breaker half-open state with limited probe requests
  • Load shedding and rate limiting to protect the recovering service
  • Gradual traffic ramp-up using canary releases or weighted routing
  • Real-time monitoring and adaptive control based on service health metrics
  • Queueing and request prioritization to manage bursty traffic

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