← Ramp Interview Insights

Ramp·Software Engineer·Technical Phone Screen·Senior

Senior
Jun 2026

Summary

Ramp SWE interview that went deep into a banking system design problem. The core challenge kept expanding with each follow-up, which I did not fully anticipate going in.

Questions Asked (4)

Q1

Design a banking system with account creation, deposits, transfers, a top-activity ranking by outgoing transaction volume, and a pay operation that schedules a 2% cashback 24 hours after the transaction.

System DesignData ModelingAlgorithms & Data Structures
Author's notes

The cashback scheduling part is what tripped me up first.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and scale, then design the core data model and APIs for accounts, transactions, and transfers. Address the ranking and scheduled cashback as separate concerns, explaining how you would implement them efficiently and reliably.

Pro tip: Emphasize idempotency and exactly-once processing for transfers and cashback, as financial systems demand strong consistency and fault tolerance. Also, discuss how you would handle race conditions and ensure data integrity under high concurrency.

1. Clarify Requirements and Scale

Ask about expected user base, transaction volume, consistency needs, and latency requirements. Clarify whether the ranking is global or per-user, and if cashback is per transaction or aggregated.

2. Design Data Model and APIs

Define entities: User, Account, Transaction, Transfer, and Cashback. Specify APIs for account creation, deposit, transfer, pay, and top-activity ranking. Choose a relational database for ACID guarantees.

3. Implement Core Operations

Detail how deposits and transfers work with transactions and locking to prevent race conditions. For transfers, use a two-phase commit or saga pattern if distributed. Ensure idempotency with unique request IDs.

4. Handle Ranking and Scheduled Cashback

For ranking, maintain a sorted set (e.g., Redis ZSET) updated on each outgoing transaction, or compute periodically from a materialized view. For cashback, use a delayed job queue (e.g., RabbitMQ with TTL, or a scheduler) to credit 2% after 24 hours, ensuring idempotency.

5. Address Scalability and Reliability

Discuss sharding, replication, and caching for read-heavy ranking. For cashback, ensure exactly-once processing with retries and dead-letter queues. Monitor and alert on failures.

Key Points to Mention

  • ACID transactions and isolation levels for financial operations
  • Idempotency keys to prevent duplicate transfers and cashback
  • Use of a sorted set or materialized view for efficient top-activity ranking
  • Delayed job scheduling with a message queue or database-backed scheduler
  • Handling race conditions with optimistic or pessimistic locking
  • Scalability considerations: sharding, caching, and read replicas

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

Q2

Extend the banking system to support merging two accounts: the merged account inherits the combined balance, combined outgoing totals for ranking, and any pending cashbacks originally tied to the absorbed account. Payment status lookups using the old account's payment IDs should still work after the merge.

System DesignData ModelingTechnical Trade-offs
Author's notes

This is where I fumbled a bit.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the requirements and constraints, such as whether the merge is permanent and how payment IDs are structured. Then propose a data model that supports merging, focusing on maintaining a mapping from old payment IDs to the merged account and aggregating balances and totals. Finally, discuss trade-offs between different approaches, such as physical merge vs. logical merge, and how to handle pending cashbacks and ranking updates.

Pro tip: Emphasize idempotency and atomicity: ensure the merge operation can be safely retried and that payment lookups remain consistent even if the merge fails midway. Also, consider using an alias table or a union-find structure to efficiently redirect old payment IDs.

1. Clarify Requirements and Constraints

Ask questions to understand the scope: Is the merge permanent? Can accounts be merged multiple times? How are payment IDs generated and stored? What are the consistency and latency requirements for payment lookups?

2. Design Data Model for Merging

Propose a schema that supports merging, such as an accounts table with a merged_into field or a separate account_aliases table. Consider how to store combined balance and outgoing totals, and how to associate pending cashbacks with the merged account.

3. Handle Payment ID Redirection

Design a mechanism to map old payment IDs to the merged account, such as a payment_id_mapping table or embedding the account ID in the payment ID. Ensure lookups are efficient and can handle multiple merges.

4. Implement Merge Operation

Outline the steps to perform the merge atomically: update balances, transfer pending cashbacks, update outgoing totals for ranking, and create mappings for old payment IDs. Discuss how to handle failures and ensure idempotency.

5. Discuss Trade-offs and Scalability

Compare approaches: physical merge (updating all records) vs. logical merge (using aliases). Discuss trade-offs in terms of read/write performance, storage, and complexity. Address how the solution scales with many merges and high lookup volume.

Key Points to Mention

  • Idempotency and atomicity of the merge operation to handle retries and failures.
  • Data model choices: account aliases, merged_into field, or union-find for efficient redirection.
  • Payment ID mapping strategy: separate mapping table vs. encoding account ID in payment ID.
  • Handling pending cashbacks: transferring ownership and ensuring they are credited to the merged account.
  • Updating outgoing totals for ranking: aggregation and potential need for recalculation.
  • Trade-offs between physical and logical merge: performance, storage, and complexity.

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

Q3

How would you keep the top-activity ranking correct after an account merge, given that the ranking is based on total outgoing transaction amounts?

Algorithms & Data StructuresSystem Design
Author's notes

Shorter discussion than I expected.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the data model and merge semantics: the ranking is based on total outgoing transaction amounts per account, and a merge combines two accounts into one. Then propose a solution that recomputes or incrementally updates the merged account's total and adjusts the ranking data structure (e.g., a balanced BST or heap) to reflect the new total, ensuring correctness and efficiency.

Pro tip: Mention that you would handle the merge atomically and consider concurrency: use a transaction or lock to prevent ranking queries from seeing an inconsistent state during the merge. Also, discuss how to handle frequent merges by batching or using a lazy update strategy if needed.

1. Clarify requirements and constraints

Ask about the scale (number of accounts, transactions), frequency of merges, and whether the ranking must be real-time or can be eventually consistent. Confirm that the ranking is global and based on total outgoing amount.

2. Design the ranking data structure

Propose a data structure that supports efficient updates and queries, such as a balanced binary search tree (e.g., order-statistic tree) or a skip list, where each node stores the account ID and total outgoing amount, sorted by amount.

3. Handle the merge operation

When merging account A into account B, compute the new total outgoing amount for B as sum(A.total, B.total). Remove A from the ranking structure and update B's total in the structure (which may involve rebalancing).

4. Ensure atomicity and consistency

Perform the merge and ranking updates within a single transaction or under a lock to prevent concurrent reads from seeing an inconsistent state. Consider using a versioned or snapshot approach for read-heavy workloads.

5. Optimize for performance and scalability

If merges are frequent, discuss incremental updates versus periodic recomputation. For very large scale, consider sharding the ranking by amount ranges or using a distributed system with eventual consistency.

Key Points to Mention

  • Data structure choice: balanced BST (e.g., red-black tree) or skip list for O(log n) updates and queries.
  • Merge semantics: sum the total outgoing amounts of both accounts and update the merged account's total.
  • Atomicity: use transactions or locks to ensure the merge and ranking update are atomic.
  • Concurrency: handle concurrent reads/writes, possibly with read-write locks or MVCC.
  • Scalability: consider sharding, caching, or batch processing for high merge rates.
  • Edge cases: merging accounts with no transactions, self-merges, or circular merges.

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

Q4

Implement GET_BALANCE so it returns the current balance after applying any cashbacks that are now due, or null if the account does not exist.

Algorithms & Data StructuresData Modeling
Author's notes

Felt like a relief after the merge question.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Clarify the data model and cashback rules, then design an efficient algorithm that retrieves the account, computes due cashbacks based on time or transaction history, and returns the updated balance or null. Discuss trade-offs between precomputing cashbacks and calculating on-the-fly, and handle edge cases like missing accounts and concurrent updates.

Pro tip: Demonstrate awareness of real-world constraints: cashback accrual might be asynchronous, so consider idempotency and consistency (e.g., using timestamps or versioning) to avoid double-counting when GET_BALANCE is called multiple times.

1. Clarify requirements and data model

Ask about the account data structure, how cashbacks are stored (e.g., pending vs applied), and the rules for when a cashback becomes due (time-based, transaction-based, etc.).

2. Design the algorithm

Outline steps: fetch account by ID, if not found return null; otherwise, identify all due cashbacks, apply them to the balance, and return the new balance. Consider whether to update the stored balance or compute on the fly.

3. Handle edge cases and concurrency

Address scenarios like no due cashbacks, multiple cashbacks, concurrent calls, and idempotency. Discuss locking or atomic operations if needed.

4. Analyze complexity and trade-offs

Evaluate time and space complexity of your approach. Compare precomputing cashbacks (faster reads, complex writes) vs computing on read (simpler writes, potentially slower reads).

5. Test and validate

Walk through test cases: existing account with/without due cashbacks, non-existent account, multiple cashbacks, and boundary conditions (e.g., cashback exactly at due time).

Key Points to Mention

  • Data modeling: how accounts and cashbacks are represented (e.g., separate cashback table with status and due date).
  • Time handling: using timestamps to determine due cashbacks and ensuring timezone consistency.
  • Idempotency: ensuring repeated GET_BALANCE calls don't apply the same cashback multiple times.
  • Concurrency: using transactions or locks to prevent race conditions when updating balance.
  • Complexity: O(1) or O(log n) lookup for account, O(k) for k due cashbacks; trade-offs of precomputation.
  • Edge cases: null for missing account, zero due cashbacks, and cashbacks that become due exactly at query time.

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