← DoorDash Interview Insights

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

Senior
May 2026

Summary

DoorDash system design round focused entirely on building an API aggregator that fans out to three backend services. Pretty meaty question with a lot of surface area, from latency budgets to circuit breakers to partial failure handling.

Questions Asked (5)

Q1

Design a single aggregator endpoint that calls three independent downstream services in parallel, combines their responses, and handles partial failures gracefully while meeting a p95 latency target under 300ms.

System DesignAPI & IntegrationsTechnical Trade-offs
Author's notes

This question has a lot of layers and I spent probably too long on the API contract before getting to the interesting parts.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and constraints, then outline a high-level design using parallel calls with timeouts and fallbacks. Dive into failure handling strategies and latency optimizations, and finally discuss trade-offs and monitoring.

Pro tip: Emphasize that partial failures should be handled by returning degraded but useful responses, and that the p95 latency target requires careful timeout budgeting and possibly hedged requests.

1. Clarify Requirements

Ask about the expected response format, criticality of each service, and acceptable degradation. Confirm the p95 latency target and whether it's end-to-end or per-service.

2. High-Level Design

Propose an aggregator service that fans out requests to the three downstream services in parallel using async I/O or a thread pool. Combine responses into a single payload.

3. Failure Handling

Define per-service timeouts and fallbacks (e.g., cached data, default values, or omitting the field). Use a circuit breaker to avoid cascading failures and return partial results with appropriate status codes.

4. Latency Optimization

Set aggressive timeouts (e.g., 250ms) to stay under p95 target. Consider hedged requests for tail latency, connection pooling, and keeping the aggregator stateless for scalability.

5. Trade-offs & Monitoring

Discuss consistency vs availability trade-offs. Propose metrics (latency, error rates per service) and logging for debugging. Mention testing strategies like chaos engineering.

Key Points to Mention

  • Parallel execution using async I/O (e.g., CompletableFuture, asyncio) or thread pools
  • Per-service timeouts and fallback strategies (cached data, defaults, partial responses)
  • Circuit breaker pattern to prevent cascading failures
  • Hedged requests to mitigate tail latency and meet p95 target
  • Returning appropriate HTTP status codes (e.g., 207 Multi-Status) for partial failures
  • Monitoring and alerting on downstream service health and aggregator latency

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

Q2

How would you represent partial failures in the response schema when one or more downstream services are unavailable or return errors?

API & IntegrationsTechnical Trade-offs
Author's notes

Went with a wrapper object per service, something like a status field and a nullable data field.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by acknowledging that partial failures are inevitable in distributed systems and should be explicitly represented in the API response schema. Propose a consistent envelope structure that separates successful data from error details, and discuss trade-offs between granularity and simplicity. Emphasize that the schema should allow clients to distinguish between complete success, partial success, and total failure.

Pro tip: Consider idempotency and retry semantics: if a downstream service fails, the client may need to retry only the failed parts. Design the schema to include a retryable flag or a list of failed operations so clients can act intelligently without re-fetching everything.

1. Define the response envelope

Propose a top-level structure that includes a status field (e.g., 'success', 'partial', 'failure') and separate sections for data and errors. This makes the overall outcome explicit.

2. Represent per-service results

For each downstream service, include an object with its own status, data (if successful), and error details (if failed). Use a consistent format across services.

3. Include error details

Provide actionable error information such as error codes, messages, and whether the error is transient or permanent. This helps clients decide whether to retry.

4. Discuss trade-offs

Compare approaches: a flat list of errors vs. nested per-service results; always returning 200 OK vs. using HTTP status codes like 207 Multi-Status. Explain when each is appropriate.

5. Address client handling

Explain how clients should interpret the schema, including how to merge partial data, display errors, and retry failed operations. Mention idempotency keys if relevant.

Key Points to Mention

  • Use of a consistent envelope with status, data, and errors fields.
  • Per-service status and error details to pinpoint failures.
  • HTTP status code choices: 200 OK with error body vs. 207 Multi-Status vs. 5xx for total failure.
  • Inclusion of retryable flags or error types to guide client retry logic.
  • Idempotency and partial update semantics to avoid duplicate side effects.
  • Trade-offs between granularity (more detail) and simplicity (easier client parsing).

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 set timeouts and retries for the downstream service calls in your aggregator.

System DesignTechnical Trade-offs
Author's notes

Per-service timeouts with a shared deadline context propagated across all three calls.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the aggregator's requirements and the downstream services' characteristics, then propose a layered strategy: set timeouts based on latency percentiles, use retries with exponential backoff and jitter, and implement circuit breakers to prevent cascading failures. Emphasize trade-offs between latency, reliability, and resource usage, and discuss how to monitor and adjust these settings.

Pro tip: Mention that you'd set timeouts slightly above the p99 latency of each downstream service and use retry budgets to cap total retries, preventing retry storms. Also, highlight the importance of idempotency keys for safe retries.

1. Clarify requirements and constraints

Ask about the aggregator's SLA, expected traffic, and the criticality of each downstream service. Understand whether calls are idempotent and what the failure modes are.

2. Set timeouts based on latency percentiles

For each downstream service, analyze historical latency data (e.g., p95, p99) and set timeouts slightly above the p99 to avoid premature failures while ensuring slow calls don't block the aggregator.

3. Implement retries with exponential backoff and jitter

Retry only on transient errors (e.g., timeouts, 5xx) with exponential backoff and jitter to avoid thundering herd. Limit retries to 2-3 attempts and use a retry budget to cap total retries across the system.

4. Add circuit breakers and fallbacks

Use circuit breakers to stop calling a failing service after a threshold, preventing cascading failures. Define fallback responses (e.g., cached data, defaults) to maintain partial functionality.

5. Monitor, measure, and iterate

Instrument metrics (latency, error rates, retry counts) and set up alerts. Continuously review and adjust timeout and retry settings based on observed behavior and changing service characteristics.

Key Points to Mention

  • Timeout values should be based on latency percentiles (e.g., p99) and not arbitrary.
  • Retries should use exponential backoff with jitter to avoid synchronized retries.
  • Retry budgets or caps prevent retry storms and resource exhaustion.
  • Circuit breakers and fallbacks isolate failures and improve resilience.
  • Idempotency is crucial for safe retries; use idempotency keys.
  • Monitoring and dynamic adjustment of timeouts/retries are essential for production systems.

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

Q4

What observability would you add to this aggregator service, and how would you use circuit breakers or bulkheads to improve reliability?

System DesignTechnical Trade-offs
Author's notes

Talked through per-service error rate metrics, latency histograms, and distributed tracing with a span per downstream call.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the aggregator's role and critical dependencies, then propose a layered observability strategy covering metrics, logs, and traces with specific examples. For reliability, explain how circuit breakers prevent cascading failures and bulkheads isolate resource pools, and tie both to concrete failure scenarios and trade-offs.

Pro tip: Emphasize that observability should drive actionable alerts and that circuit breakers and bulkheads must be tuned based on SLOs and load testing—not just added blindly. Mention that you'd validate resilience patterns with chaos experiments to ensure they work under real failure conditions.

1. Clarify the system and failure modes

Ask about the aggregator's dependencies, traffic patterns, and SLOs to ground your answer. Identify likely failure modes such as slow downstream services, partial outages, and traffic spikes.

2. Propose observability instrumentation

Outline metrics (latency, error rates, saturation, dependency health), structured logs with correlation IDs, and distributed tracing to pinpoint bottlenecks. Suggest dashboards and alerts tied to SLOs.

3. Explain circuit breakers

Describe how circuit breakers detect failures and open to fail fast, preventing cascading failures. Discuss configuration (thresholds, timeouts, half-open state) and fallback strategies.

4. Explain bulkheads

Explain how bulkheads isolate resources (e.g., thread pools, connection pools) per dependency to contain failures. Give an example of limiting concurrent calls to a slow service so it doesn't exhaust shared resources.

5. Discuss trade-offs and validation

Address trade-offs like added complexity, latency from circuit breaker timeouts, and resource overhead from bulkheads. Mention testing via chaos engineering and tuning based on observed behavior.

Key Points to Mention

  • Use RED metrics (Rate, Errors, Duration) for the aggregator and its dependencies.
  • Implement distributed tracing with context propagation to trace requests across services.
  • Configure circuit breakers with failure thresholds, timeouts, and half-open state to recover gracefully.
  • Apply bulkheads to isolate thread pools or connection pools per downstream dependency.
  • Define fallbacks (cached responses, defaults) when circuit breakers open.
  • Validate resilience with chaos experiments and load testing, and tune parameters based on SLOs.

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

Q5

How does your aggregator design scale under high request volume, and what are the main bottlenecks you'd expect?

System DesignTechnical Trade-offs
Author's notes

Stateless service so horizontal scaling is straightforward.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the aggregator's role and expected scale, then walk through the architecture layer by layer, identifying potential bottlenecks at each stage. Emphasize horizontal scaling, caching, and asynchronous processing, and discuss trade-offs between consistency and availability. Conclude with monitoring and auto-scaling strategies to handle high volume.

Pro tip: Quantify bottlenecks with rough numbers (e.g., QPS, latency) to show practical experience, and mention how you'd validate assumptions with load testing and metrics. This demonstrates a data-driven approach and maturity.

1. Clarify requirements and scale

Ask about expected request volume, latency SLAs, data consistency needs, and aggregator's role (e.g., fan-out to multiple services). This ensures your answer is tailored to the actual scenario.

2. Describe the high-level architecture

Outline the aggregator's components: load balancer, stateless service instances, cache, downstream services, and data stores. Explain how requests flow through the system.

3. Identify scaling strategies

Discuss horizontal scaling of stateless services, caching (e.g., Redis) for repeated queries, asynchronous processing (e.g., message queues) for non-critical tasks, and database sharding/read replicas.

4. Analyze bottlenecks

Walk through each layer: network I/O, CPU, memory, downstream service limits, database contention, and cache misses. Explain how each could become a bottleneck under high load.

5. Propose mitigation and monitoring

Suggest solutions like rate limiting, circuit breakers, backpressure, auto-scaling, and comprehensive monitoring (metrics, tracing) to detect and address bottlenecks proactively.

Key Points to Mention

  • Horizontal scaling with stateless services and load balancing
  • Caching strategies (e.g., Redis) to reduce downstream load and latency
  • Asynchronous processing and message queues for decoupling and burst handling
  • Database scaling: read replicas, sharding, and connection pooling
  • Rate limiting, circuit breakers, and backpressure to prevent overload
  • Monitoring, metrics, and load testing to identify and validate bottlenecks

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