← Databricks Interview Insights

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

Senior
May 2026

Summary

System design round at Databricks for a software engineering role, focused entirely on building a stock trading system on top of a third-party exchange API. Pretty deep dive, lots of follow-up on failure modes and scalability.

Questions Asked (4)

Q1

Design a stock trading system that supports buy and sell orders (market and limit), built on top of a third-party exchange API with endpoints to post, query, and cancel orders.

System DesignAPI & IntegrationsData Modeling
Author's notes

I started with the data model and order lifecycle which felt right, but I think I underexplained the state machine early on.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying functional and non-functional requirements, then design a layered architecture that separates order management, risk checks, and exchange integration. Focus on how you model orders, handle state transitions, and ensure reliability when interacting with the third-party API.

Pro tip: Emphasize idempotency and reconciliation: since the exchange API can fail or be slow, design your system to safely retry and periodically reconcile local order state with the exchange to avoid duplicate or lost orders.

1. Clarify Requirements and Scope

Ask about expected order volume, latency requirements, supported order types (market/limit), and whether the system needs to handle multiple accounts or exchanges. This sets the stage for design decisions.

2. Design Data Model and Order Lifecycle

Define entities like Order, Trade, and Position, and map out the order state machine (e.g., PENDING, OPEN, PARTIALLY_FILLED, FILLED, CANCELLED, REJECTED). Consider how to store orders and trades for auditing and querying.

3. Architect Core Components

Outline services: API gateway, order management service, risk engine, and exchange adapter. Explain how they interact, and how you handle synchronous vs. asynchronous flows (e.g., order placement vs. fill updates).

4. Integrate with Third-Party Exchange API

Detail how to use the post, query, and cancel endpoints. Discuss idempotency keys, retry logic with exponential backoff, rate limiting, and handling partial failures. Mention the need for a reconciliation job to sync local state with the exchange.

5. Address Scalability, Reliability, and Monitoring

Discuss partitioning by user or symbol, using message queues for async processing, and ensuring high availability. Include monitoring, alerting, and logging for order flow and exchange API health.

Key Points to Mention

  • Idempotency and exactly-once semantics when calling the exchange API to avoid duplicate orders.
  • Order state machine and how to handle asynchronous updates (e.g., fills via WebSocket or polling).
  • Risk checks (e.g., buying power, position limits) before sending orders to the exchange.
  • Reconciliation mechanism to detect and resolve discrepancies between local and exchange order states.
  • Rate limiting and backoff strategies to handle exchange API throttling.
  • Data consistency and durability: using a database with transactions or event sourcing for order events.

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

Q2

How would you reliably detect and handle order expiration based on time-in-force constraints?

System DesignTechnical Trade-offs
Author's notes

This is where I felt most out of my depth.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the requirements: what time-in-force types exist (e.g., GTC, IOC, FOK), what are the latency and accuracy requirements, and what scale (orders per second). Then propose a design that uses a time-ordered data structure (like a priority queue or timing wheel) to efficiently expire orders, and discuss trade-offs between different approaches (e.g., polling vs. event-driven, in-memory vs. persistent). Finally, address reliability concerns such as handling clock skew, failures, and ensuring exactly-once expiration.

Pro tip: Emphasize idempotency and fault tolerance: design expiration to be idempotent so that even if an expiration event is processed multiple times, it doesn't cause issues. Also, mention the importance of monitoring and alerting on expiration lag to detect system issues early.

1. Clarify requirements and constraints

Ask about the types of time-in-force (e.g., GTC, IOC, FOK, GTD), expected order volume, latency requirements, and consistency guarantees needed. This ensures the solution fits the actual use case.

2. Choose a time-based data structure

Select an efficient structure like a min-heap (priority queue) keyed by expiration time, or a hierarchical timing wheel for high-throughput scenarios. Discuss trade-offs: heaps are simple but O(log n) insert/delete; timing wheels offer O(1) but are more complex.

3. Design the expiration mechanism

Decide between active polling (a background thread checks the earliest expiration) and event-driven (scheduled timers). Consider using a dedicated expiration service or integrating with the order matching engine. Address how to handle cancellations and modifications.

4. Ensure reliability and fault tolerance

Implement idempotent expiration handlers, use persistent storage or write-ahead logs to recover after failures, and handle clock skew with NTP or logical clocks. Consider distributed coordination if multiple nodes are involved.

5. Discuss trade-offs and optimizations

Compare approaches in terms of latency, throughput, memory, and complexity. Mention optimizations like batching expirations, lazy deletion, and monitoring expiration lag to ensure SLAs are met.

Key Points to Mention

  • Time-in-force types (GTC, IOC, FOK, GTD) and their specific expiration semantics
  • Data structures: min-heap, timing wheel, or sorted set (e.g., Redis ZSET) for efficient expiration
  • Idempotency and exactly-once processing to avoid duplicate expirations
  • Clock synchronization (NTP, logical clocks) and handling clock skew
  • Fault tolerance: persistence, replication, and recovery mechanisms
  • Monitoring and alerting on expiration lag and system health

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

Q3

How do you ensure idempotency and handle retries when calling the third-party exchange API?

API & IntegrationsSystem DesignTechnical Trade-offs
Author's notes

Got this one more or less right.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the specific exchange API's guarantees (e.g., does it support idempotency keys?) and the business impact of duplicate or lost orders. Then describe a layered strategy: client-generated idempotency keys, retry with exponential backoff and jitter, and a reconciliation process to handle ambiguous failures. Emphasize trade-offs between consistency, latency, and complexity, and how you'd monitor and test the solution.

Pro tip: Mention that you'd store the idempotency key and request state in a durable, transactional store before making the API call, so that retries can be safely deduplicated even if the process crashes. This shows you understand the importance of atomicity between local state and external calls.

1. Clarify requirements and API capabilities

Ask whether the exchange API supports idempotency keys, what its rate limits and error semantics are, and what the business impact of duplicate orders is. This determines the necessary level of protection.

2. Design for idempotency

Generate a unique idempotency key per logical request and persist it with the request state before calling the API. Use the key in the API call so the server can deduplicate retries.

3. Implement robust retry logic

Use exponential backoff with jitter, set a maximum retry limit, and only retry on transient errors (e.g., timeouts, 5xx). Avoid retrying on client errors like 4xx unless they are explicitly retryable.

4. Handle ambiguous outcomes

If a request times out or fails after being sent, query the API (if possible) or use a reconciliation job to determine the final state. Never assume failure without verification.

5. Monitor, test, and iterate

Instrument metrics for retries, duplicates, and latency; write tests simulating network failures and duplicate responses. Continuously refine based on observed behavior.

Key Points to Mention

  • Idempotency keys: client-generated unique identifiers that the server uses to deduplicate requests.
  • Exponential backoff with jitter to avoid thundering herd and reduce load on the exchange.
  • Durable storage of request state and idempotency key before making the API call to ensure crash safety.
  • Reconciliation or status-check endpoints to resolve ambiguous failures (e.g., timeouts).
  • Trade-offs: consistency vs. latency, complexity of implementation, and cost of retries.
  • Monitoring and alerting on retry rates, duplicate detection, and API error rates.

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

Q4

What are the main bottlenecks in this system at scale, and how would you address them?

System DesignTechnical Trade-offs
Author's notes

Talked through write throughput on the orders table, the synchronous latency of external API calls, and fan-out when fills need to notify downstream systems.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the system's scale, workload characteristics, and SLOs to ground your analysis. Then systematically identify bottlenecks across compute, storage, network, and coordination layers, prioritizing by impact. For each bottleneck, propose concrete mitigation strategies with trade-offs, and tie them back to Databricks' distributed data processing context.

Pro tip: Quantify bottlenecks with rough numbers (e.g., 'At 1M QPS, the metadata store becomes the bottleneck because each query requires 3 reads') to show you think in terms of scale and can prioritize effectively.

1. Clarify scale and requirements

Ask about expected scale (QPS, data volume, growth rate), latency/throughput SLOs, and workload patterns (read/write ratio, skew). This ensures your analysis is relevant and targeted.

2. Identify bottlenecks layer by layer

Walk through the system stack: compute (CPU, memory, GC), storage (disk I/O, capacity), network (bandwidth, latency), and coordination (metadata, locks). Call out the most likely bottlenecks at scale.

3. Prioritize by impact and likelihood

Rank bottlenecks based on how soon they'll hit and how severely they'll degrade performance. Focus on the critical path and single points of failure.

4. Propose mitigations with trade-offs

For each top bottleneck, suggest solutions like sharding, caching, partitioning, async processing, or horizontal scaling. Discuss trade-offs (consistency vs. availability, cost vs. performance).

5. Validate and iterate

Explain how you'd validate fixes (load testing, monitoring) and iterate. Mention that bottlenecks shift as you scale, so continuous profiling is key.

Key Points to Mention

  • Horizontal scaling and sharding strategies for compute and storage
  • Caching layers (e.g., Redis, CDN) to reduce latency and offload databases
  • Data partitioning and skew handling to avoid hotspots
  • Asynchronous processing and message queues for decoupling
  • Database optimizations: indexing, read replicas, connection pooling
  • Monitoring and observability to detect bottlenecks early (metrics, tracing)

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