Skip to main content

Preview — Pro guide

You are seeing a portion of this guide. Sign in and upgrade to unlock the full article, quizzes, and interview answers.

LLD Case Study: ATM Machine System Design

Design an ATM system covering hardware abstraction, session state machines, security constraints, and cash dispensing algorithms. Covers the exact questions FAANG interviewers probe: preventing double-dispensing, handling mid-transaction cash exhaustion, and why concurrency must be handled at the bank service layer.

50 min read 3 sections 1 interview questions
ATM System DesignState PatternState Machine DesignTemplate Method PatternChain of ResponsibilityOptimistic LockingCoin Change AlgorithmISO 9564 PIN SecurityTwo-Phase CommitHardware Abstraction LayerIdempotent TransactionsLow Level Design Interview

Why ATM Design Tests the Right Skills

ATM design is asked at Microsoft, Amazon, Thoughtworks, and Atlassian LLD rounds because it simultaneously tests three things that rarely appear together in simpler problems: hardware abstraction (CardReader, CashDispenser, Display are real physical devices with failure modes), state machine design (IDLE → CARD_INSERTED → PIN_ENTRY → AUTHENTICATED → DISPENSING → SESSION_END — each state permits exactly one set of operations), and security design (PIN storage, session timeout, card retention, transaction atomicity).

The counterintuitive insight most candidates miss: concurrency in ATMs is not the ATM's problem. The ATM is a thin terminal. Account balances are owned by the bank's core banking system. If two ATMs try to withdraw from the same account simultaneously, the race condition must be resolved at the bank service layer via optimistic locking on the account balance version — not at the ATM via distributed locks. The ATM simply calls the bank's debit API and handles the response: success, insufficient funds, or conflict (retry). Candidates who propose distributed locking at the ATM layer reveal they haven't thought about where state actually lives.

A second non-obvious issue: double-dispensing. If cash is dispensed but the network call to confirm the transaction fails, the ATM has given out money but the bank's system may not have debited the account. Production ATMs handle this with a two-phase commit pattern: record the intent to dispense (persisted to local journal), then dispense, then confirm. If confirm fails, the ATM sends a reversal on the next network reconnect. This is never covered in tutorial content.

TIP

What Interviewers Are Evaluating

Mid-level: Can you identify the core entities (ATM, Card, Session, Transaction, BankAccount)? Do you model the state machine correctly? Can you implement a basic withdraw flow?

Senior-level: Do you identify that concurrency belongs at the bank service layer? Can you explain the double-dispensing problem and the two-phase commit solution? Do you model the hardware components as abstracted interfaces?

Staff-level: Do you reason about the cash dispensing algorithm (greedy fails for some denomination sets — when is DP required)? Do you handle partial failures (network timeout mid-dispense)? Do you design for offline ATM operation (local journal + reconciliation)?

IMPORTANT

Premium content locked

This guide is premium content. Upgrade to Pro to unlock the full guide, quizzes, and interview Q&A.