← Coinbase Interview Insights

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

SeniorPrefer not to say
May 2026Remote

Summary

Coinbase software engineer interview that went deep into system design for a banking system. Four parts, each one building on the last, and by the end I was pretty much designing a mini fintech backend from scratch. The scope was bigger than I expected.

Questions Asked (4)

Q1

Design and implement an in-memory banking system with CreateAccount and Transfer operations. Your solution needs to handle validation for nonnegative amounts, sufficient funds, account existence, and atomic balance updates. How do you make transfers idempotent using transaction IDs?

System DesignAlgorithms & Data StructuresTechnical Trade-offs
Author's notes

The idempotency part is where I stumbled.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and constraints, then design a simple in-memory data model with accounts and a transaction log for idempotency. Walk through the transfer algorithm step-by-step, emphasizing validation, atomicity, and idempotency, and discuss trade-offs like locking granularity and failure scenarios.

Pro tip: Demonstrate awareness of concurrency by discussing how you would prevent race conditions (e.g., per-account locks or a global lock) and how you would ensure idempotency even if the same transaction ID is retried concurrently.

1. Clarify Requirements and Constraints

Ask about expected scale, concurrency, persistence, and error handling. Confirm that amounts are nonnegative, accounts must exist, and transfers must be atomic and idempotent.

2. Design Data Model

Propose an in-memory structure: a map of account IDs to balances, and a map of transaction IDs to transfer records (or a set of processed transaction IDs) for idempotency.

3. Implement Core Operations

Define CreateAccount (initialize balance to zero) and Transfer (validate, check funds, update balances atomically). Use a lock or transactional mechanism to ensure atomicity.

4. Ensure Idempotency

Before processing a transfer, check if the transaction ID has already been processed. If so, return the previous result (or success) without reapplying the transfer.

5. Discuss Trade-offs and Edge Cases

Talk about locking strategies (global vs per-account), memory usage, failure recovery, and how to handle concurrent requests with the same transaction ID.

Key Points to Mention

  • Use a map/dictionary for accounts and a separate map or set for transaction IDs to track idempotency.
  • Validate nonnegative amounts, sufficient funds, and account existence before any balance changes.
  • Ensure atomicity by using locks (e.g., synchronized blocks, mutexes) or transactional memory.
  • For idempotency, store the transaction ID and result (or just mark as processed) before or atomically with the balance update.
  • Consider concurrency: use per-account locks to allow parallel transfers between different accounts, but beware of deadlocks.
  • Discuss how to handle partial failures (e.g., if the system crashes mid-transfer) and whether to use a write-ahead log or two-phase commit.

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

Q2

Add a query to return the top K accounts by total outgoing transfer volume. What data structures do you use, and what are the time and space complexity tradeoffs for both updates and queries?

Algorithms & Data StructuresSystem DesignTechnical Trade-offs
Author's notes

I went straight to a sorted set and talked through maintaining a running aggregate per account.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the requirements: are updates frequent, and do we need real-time top K? Then propose a data structure like a hash map for account balances combined with a heap or balanced BST for ordering. Discuss the tradeoffs between update and query time, and consider if approximate or batch processing is acceptable.

Pro tip: Mention that in a real system like Coinbase, you might use a streaming approach with a min-heap of size K to maintain top K efficiently, and that you'd consider persistence and concurrency. Also, note that if updates are extremely frequent, a heap might not be optimal due to O(log n) updates, and you might use a bucket or count-based approach if volumes are bounded.

1. Clarify requirements

Ask about update frequency, query frequency, K size, and whether exact top K is needed. Determine if data fits in memory and if real-time updates are required.

2. Propose data structures

Suggest a hash map for account balances and a min-heap of size K for top K, or a balanced BST for ordered access. Alternatively, consider a combination like a hash map with a sorted list or a Fenwick tree for prefix sums.

3. Analyze complexities

For each structure, detail update and query time/space. For example, hash map + heap: update O(log K) if in top K, query O(K log K) to extract sorted; balanced BST: update O(log n), query O(K log n).

4. Discuss tradeoffs

Compare tradeoffs: heap is space-efficient but query requires sorting; BST allows ordered traversal but higher update cost. Consider if K is small, heap is better; if K is large, BST or sorted array might be better.

5. Consider scalability

Mention distributed or streaming approaches if data is large, like using a priority queue per shard and merging, or approximate algorithms like count-min sketch for heavy hitters.

Key Points to Mention

  • Hash map for O(1) balance updates
  • Min-heap of size K for top K tracking
  • Balanced BST (e.g., red-black tree) for ordered access
  • Time complexity: update O(log K) vs O(log n), query O(K log K) vs O(K log n)
  • Space complexity: O(n) for map, O(K) for heap, O(n) for BST
  • Tradeoff between update and query performance, and suitability for real-time vs batch

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

Q3

Implement a Purchase operation that awards 2% cashback credited exactly 24 hours after the purchase. How do you structure pending rewards, schedule the credit posting, and ensure the processing is idempotent and crash-safe?

System DesignData ModelingTechnical Trade-offs
Author's notes

This was the part that surprised me most.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and constraints, then propose a data model with a pending rewards table and a scheduled job that processes matured rewards. Emphasize idempotency via unique transaction IDs and crash safety through transactional writes and retries.

Pro tip: Mention that you would use a database transaction to atomically mark the reward as processed and credit the account, and that you would use a unique constraint on the reward ID to prevent double crediting. Also, discuss monitoring and alerting for failed jobs.

1. Clarify requirements and constraints

Ask about scale, consistency requirements, and whether the 24-hour delay is exact or approximate. Confirm that cashback is 2% of purchase amount and that crediting should happen exactly 24 hours later.

2. Design data model

Propose a pending_rewards table with fields: id, user_id, purchase_id, amount, status (pending/credited), created_at, scheduled_at, and a unique constraint on purchase_id to prevent duplicates. Also, consider a ledger table for credits.

3. Schedule and process rewards

Use a scheduled job (e.g., cron or a queue with delayed messages) that runs periodically to find pending rewards where scheduled_at <= now. Process each reward by crediting the user's account and updating the reward status.

4. Ensure idempotency and crash safety

Wrap the credit operation in a database transaction: update reward status to 'processing' with a unique transaction ID, then credit the account, then mark as 'credited'. Use idempotency keys to handle retries. If crash occurs, the transaction rolls back, and the job can retry.

5. Handle failures and monitoring

Implement retries with exponential backoff for transient failures. Log errors and set up alerts for failed rewards. Consider a dead-letter queue for persistent failures and manual intervention.

Key Points to Mention

  • Idempotency: Use unique constraints and idempotency keys to prevent double crediting.
  • Crash safety: Use database transactions to ensure atomicity of status update and credit.
  • Scheduling: Use a delayed queue or scheduled job with a polling mechanism.
  • Data model: Separate pending rewards from credited ledger for auditability.
  • Retry logic: Implement retries with backoff and dead-letter queue for failures.
  • Monitoring: Alert on failed rewards and track processing latency.

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

Q4

Design a MergeAccount operation that combines two accounts: transfer balances and transaction history to the primary account, redirect future operations from the duplicate ID, and reconcile pending cashback and any overlapping transaction IDs.

System DesignData ModelingAlgorithms & Data Structures
Author's notes

By this point I was pretty mentally cooked.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and constraints, then design the operation as an idempotent, transactional workflow that ensures atomicity and consistency. Break down the problem into data migration, ID redirection, and reconciliation of pending cashback and overlapping transaction IDs, addressing edge cases and failure recovery.

Pro tip: Emphasize idempotency and auditability: design the operation to be safely retryable and log every step for reconciliation and rollback. This shows you understand production-grade financial systems where correctness and traceability are critical.

1. Clarify Requirements and Constraints

Ask about data volume, consistency requirements, downtime tolerance, and regulatory constraints. Confirm whether the operation should be synchronous or asynchronous, and how to handle failures.

2. Design Data Migration and Balance Transfer

Plan how to move balances and transaction history to the primary account, ensuring atomicity and consistency. Consider using a two-phase commit or saga pattern if multiple services are involved.

3. Implement ID Redirection and Alias Mapping

Create a mapping from the duplicate ID to the primary ID, and update all references (e.g., in user profiles, payment methods) to redirect future operations. Ensure the mapping is persisted and used by all relevant services.

4. Reconcile Pending Cashback and Overlapping Transactions

Identify pending cashback tied to the duplicate account and transfer or re-issue it to the primary account. For overlapping transaction IDs, deduplicate and resolve conflicts based on timestamps or business rules.

5. Ensure Idempotency, Auditability, and Rollback

Make the operation idempotent using a unique operation ID, log all changes for auditing, and design a rollback plan in case of partial failure. Consider using a state machine to track progress.

Key Points to Mention

  • Idempotency: Use a unique merge operation ID to prevent duplicate processing on retries.
  • Transactional integrity: Ensure atomicity across account updates, balance transfers, and history migration.
  • Data consistency: Handle concurrent operations and use locking or optimistic concurrency control.
  • ID redirection: Maintain an alias table or mapping service to redirect future operations from the duplicate ID.
  • Reconciliation: Deduplicate overlapping transaction IDs and correctly transfer pending cashback.
  • Auditability and rollback: Log all steps and provide a mechanism to revert the merge if needed.

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