Data Lifecycle — Example: Bank ATM Withdrawal
The Scenario
A customer walks up to an ATM, inserts their card, enters their PIN, requests $200 cash, and walks away with the money and a receipt.
This is one of the most data-sensitive operations in everyday life. Every piece of data must be exact. There is zero tolerance for error — if the system says the customer has $500, they must have exactly $500. Not $499.99, not $500.01.
Let's map it.
Step 1: Identify All the Data
Obvious data:
- Card data (account number, card info)
- PIN
- Withdrawal amount ($200)
- Account balance
- Cash dispensed
- Receipt
Less obvious data:
- ATM's physical cash inventory (does it have enough $20 bills?)
- Daily withdrawal limit for this account
- How much the customer has already withdrawn today
- ATM network session (the encrypted connection between ATM and bank)
- Transaction authorization code
- ATM location and ID
- Timestamp of the transaction
- Account hold/freeze status
- Currency denomination preferences (does the ATM give $20s, $50s, or $100s?)
- ATM's own status (is the receipt printer working? is the cash drawer jammed?)
- Fraud detection signals (is this card being used in a different country than it was 5 minutes ago?)
Step 2: Full Lifecycle Map
| # | Stage | What Happens | Category | Key Details |
|---|---|---|---|---|
| 1 | Card inserted | ATM reads magnetic stripe or chip data | Transport (card → ATM) | Card number, expiry, bank identifier extracted |
| 2 | Card data stored temporarily | ATM holds card data in encrypted memory | Storage (temporary, encrypted) | Never written to disk. Held only for this session. |
| 3 | ATM connects to bank network | Encrypted session established | Transport (ATM → bank) | Session ID, ATM ID, ATM location transmitted |
| 4 | Card data sent for validation | ATM sends card info to bank | Transport (ATM → bank) | Card number + bank identifier |
| 5 | Bank validates card | Is this a real card? Is it active? Is it reported stolen? Expired? | Transform (validation) | Card status checked against bank records |
| 6 | Card status returned | Bank sends result back to ATM | Transport (bank → ATM) | "Valid" or specific rejection reason |
| 7 | PIN prompt displayed | ATM asks customer for PIN | Transport (ATM → customer screen) | No data in transit — just a UI prompt |
| 8 | Customer enters PIN | Keypad captures digits | Transport (keypad → ATM memory) | PIN stored encrypted, never displayed on screen |
| 9 | PIN sent for verification | Encrypted PIN sent to bank | Transport (ATM → bank) | PIN is encrypted end-to-end. ATM never knows the real PIN. |
| 10 | Bank verifies PIN | Entered PIN compared to stored PIN hash | Transform (comparison) | Bank doesn't store plaintext PINs either — it compares hashes |
| 11 | PIN result returned | Bank sends verification result | Transport (bank → ATM) | "Correct" or "incorrect" + remaining attempts count |
| 12 | Customer selects "Withdrawal" | Selection captured | Storage (temporary) | Transaction type stored in session |
| 13 | Customer enters $200 | Amount captured | Storage (temporary) | Amount stored in session |
| 14 | ATM checks local cash | Does ATM have enough cash to dispense? | Transform (comparison) | $200 requested vs. ATM cash inventory |
| 15 | Withdrawal request sent to bank | ATM sends full transaction request | Transport (ATM → bank) | Account, amount, ATM ID, timestamp |
| 16 | Bank checks balance | Is current balance ≥ $200? | Transform (comparison) | Available balance (accounting for holds and pending transactions) |
| 17 | Bank checks daily limit | Has customer exceeded daily withdrawal limit? | Transform (comparison) | Today's total withdrawals + $200 vs. limit |
| 18 | Bank checks fraud signals | Is this transaction suspicious? | Transform (analysis) | Location, timing, amount patterns checked |
| 19 | Bank authorizes (or denies) | All checks pass → generate authorization | Transform | Creates authorization code, places temporary hold on funds |
| 20 | Funds held (not yet deducted) | Bank places a hold of $200 on the account | Storage (state change) | Available balance reduced by $200, but actual balance not yet changed |
| 21 | Authorization sent to ATM | Bank sends approval + auth code | Transport (bank → ATM) | Authorization code, approved amount |
| 22 | ATM dispenses cash | Physical mechanism releases bills | Transport (ATM cash drawer → customer) | $200 in $20 bills. ATM cash inventory reduced. |
| 23 | Customer takes cash | ATM sensors detect cash was taken | Transform (state change) | Transaction status: "cash dispensed" |
| 24 | Dispensing confirmed to bank | ATM tells bank: cash was taken successfully | Transport (ATM → bank) | Auth code + "dispensed" confirmation |
| 25 | Bank finalizes transaction | Hold converted to actual deduction. Balance permanently reduced. | Transform (state change) | Available balance and actual balance both reduced. Transaction recorded. |
| 26 | Transaction logged | Full record written to bank's transaction database | Storage (persistent, permanent) | Account, amount, ATM ID, location, timestamp, auth code |
| 27 | Receipt printed | ATM formats and prints receipt | Transform + Transport | Transaction data → receipt format → printed paper |
| 28 | Session ended | All temporary data in ATM memory cleared | Storage (destruction) | Card data, PIN, session data all wiped |
Step 3: Critical Data Detail — The Two-Phase Commit
Notice stages 20 and 25. This is the most important concept in this example:
The bank does NOT deduct the money when it authorizes the transaction. It places a hold first.
Why? Because of the gap between stages 21-24. What if:
- The ATM authorizes the withdrawal but then jams and can't dispense cash?
- The customer walks away without taking the money?
- The network drops between authorization and dispensing confirmation?
If the bank had already deducted the money at step 19, the customer would lose $200 they never received. Instead:
- Phase 1 (Hold): Money is reserved but not gone. If something fails, the hold is released and the customer's balance is restored.
- Phase 2 (Finalize): Only after the ATM confirms the cash was taken does the bank permanently deduct.
This is called a two-phase commit and it exists specifically because transport between ATM and bank can fail at any point. The data lifecycle design accounts for the worst case.
Step 4: Hidden Data Analysis
| Hidden Data | Type | Where It Lives | Why It Matters |
|---|---|---|---|
| PIN attempt counter | State | Bank's card record | After 3 wrong PINs, card is locked. Counter resets on success. |
| ATM cash inventory by denomination | State | ATM local storage | ATM must know exactly how many $20s, $50s, $100s it has. If inventory tracking is wrong, it could promise cash it can't deliver. |
| Daily withdrawal running total | Derived | Bank's transaction records | Calculated from today's transactions. Not stored as a single number — derived from the sum of today's withdrawals. |
| Transaction sequence number | Metadata | Both ATM and bank | Ensures no transaction is processed twice, even if network hiccups cause a retry. |
| ATM hardware status | State | ATM local diagnostics | Printer jammed? Card reader failing? Cash drawer low? These are all data that affect whether the ATM can complete a transaction. |
| Authorization expiry | Configuration | Bank rules | A hold might expire after 24 hours if not finalized. This prevents money from being locked indefinitely. |
| Fraud scoring signals | Derived | Bank's fraud detection system | Geographic velocity (was this card used 1000 miles away 10 minutes ago?), amount patterns, time-of-day patterns. |
Step 5: What Could Go Wrong
| Failure Point | What Happens | Consequence | Correct Response |
|---|---|---|---|
| Network fails after PIN, before authorization | ATM can't reach bank | Transaction cannot proceed | Return card. Display "service unavailable." Don't guess. |
| Authorization granted, but ATM cash drawer jams | Cash can't be dispensed | Customer authorized but didn't receive money | ATM sends "dispensing failed" to bank. Bank releases hold. Customer balance restored. |
| Network fails after cash dispensed, before confirmation | ATM can't tell bank the cash was taken | Bank doesn't know to finalize | Bank's hold expires → money returns to account. But customer HAS the cash. Bank reconciles from ATM's local transaction log during next sync. |
| Power failure mid-transaction | Everything stops | Unclear state | ATM writes transaction state to non-volatile storage at each step. On reboot, it replays the state to determine where it stopped and what needs recovery. |
| Customer walks away without taking cash | Cash is hanging out of the machine | Security risk + accounting mismatch | ATM retracts cash after timeout (usually 30 seconds). Sends "cash retracted" to bank. Hold released. |
Compare and Contrast With the Coffee Example
| Aspect | Coffee Shop | ATM Withdrawal |
|---|---|---|
| Data sensitivity | Low-medium (order data, payment token) | Maximum (financial records, PINs) |
| Error tolerance | Medium (wrong order is bad, but fixable) | Zero (wrong balance is unacceptable) |
| Two-phase commit needed? | No (charge and order can be atomic) | Yes (must handle gap between authorization and dispensing) |
| Physical-digital boundary | Barista → digital status update | Cash drawer → sensors → digital confirmation |
| Failure cost | Bad customer experience | Financial loss or fraud |
| Hidden data volume | Moderate | Extensive (fraud signals, hardware status, attempt counters) |
The key lesson: the lifecycle structure is the same (storage → transform → transport), but the stakes change everything about how carefully you map it. In the coffee app, missing a notification is annoying. In the ATM system, missing a transaction confirmation means someone loses money.
When you design a system, the first question after "what is the data lifecycle?" is: "What are the stakes when it fails?" The answer determines how much detail your map needs.