ATM System Design - Complete Low-Level Design Guide
Design a scalable ATM System using Java and Spring Boot. Learn requirement analysis, UML class diagrams, cash dispensing algorithms, transaction processing, security, concurrency, SOLID principles, design patterns, and enterprise architecture.
Introduction
The ATM (Automated Teller Machine) System is one of the most popular Low-Level Design (LLD) interview questions because it combines object-oriented design, transaction management, hardware integration, security, concurrency, and financial workflows.
Every day, millions of ATM transactions are processed worldwide.
Banks such as:
- Chase
- Bank of America
- Wells Fargo
- Citi
- HSBC
- ICICI
- HDFC
- SBI
must ensure that every transaction is:
- Secure
- Accurate
- Fast
- Fault Tolerant
- Consistent
Unlike many interview problems, an ATM system involves both software and hardware components, making it an excellent exercise for learning enterprise application design.
Problem Statement
Design an ATM System that allows customers to:
- Authenticate using ATM Card and PIN
- View Account Balance
- Withdraw Cash
- Deposit Cash
- Transfer Funds
- Change PIN
- Print Receipt
- Mini Statement
- Eject Card
The system should securely communicate with the bank core system.
Functional Requirements
The ATM should support:
- Card Authentication
- PIN Verification
- Cash Withdrawal
- Cash Deposit
- Balance Inquiry
- Fund Transfer
- Mini Statement
- PIN Change
- Receipt Generation
- Session Timeout
- Card Ejection
Non-Functional Requirements
The system should be:
- Highly Secure
- Highly Available
- Fault Tolerant
- Thread Safe
- Maintainable
- Extensible
- Transaction Safe
- PCI DSS Compliant
Actors
Actors include:
- Customer
- ATM Machine
- Bank Server
- Payment Network
- Cash Dispenser
- Receipt Printer
- Card Reader
High-Level Architecture
flowchart TD
CUSTOMER["Customer"]
ATM["ATM Device"]
AUTH["Auth Service (PIN + Card)"]
TXN["Transaction Engine"]
CORE["Bank Core Banking System"]
CASH["Cash Dispenser Module"]
PRINTER["Receipt Printer Module"]
CUSTOMER --> ATM
ATM --> AUTH
ATM --> TXN
ATM --> CORE
ATM --> CASH
ATM --> PRINTER
Core Components
The ATM system consists of:
- ATM Machine
- ATM Card
- Customer
- Account
- Transaction
- Cash Dispenser
- Card Reader
- PIN Validator
- Receipt Printer
- Bank Server
Domain Model
classDiagram
class ATM
class ATMCard
class Customer
class Account
class Transaction
class CashDispenser
class CardReader
class ReceiptPrinter
ATM --> CardReader
ATM --> CashDispenser
ATM --> ReceiptPrinter
Customer --> ATMCard
ATMCard --> Account
Account --> Transaction
Entity Responsibilities
ATM
Responsible for:
- Session Management
- Transaction Flow
- Hardware Coordination
ATM Card
Stores:
- Card Number
- Expiry Date
- Card Status
Customer
Stores:
- Customer ID
- Name
- Contact Information
Account
Stores:
- Account Number
- Balance
- Account Type
- Status
Transaction
Stores:
- Transaction ID
- Type
- Amount
- Timestamp
- Status
Cash Dispenser
Responsible for:
- Cash Inventory
- Dispensing Notes
- Cash Validation
Card Reader
Responsible for:
- Reading Card
- Detecting Card Removal
Receipt Printer
Prints:
- Transaction Receipt
- Mini Statement
ATM Workflow
sequenceDiagram
participant Customer
participant ATM
participant Bank
Customer->>ATM: Insert Card
ATM->>Customer: Enter PIN
Customer->>ATM: PIN
ATM->>Bank: Authenticate
Bank-->>ATM: Success
ATM-->>Customer: Show Menu
Cash Withdrawal Flow
sequenceDiagram
participant Customer
participant ATM
participant Bank
participant CashDispenser
Customer->>ATM: Withdraw $200
ATM->>Bank: Validate Balance
Bank-->>ATM: Approved
ATM->>CashDispenser: Dispense Cash
CashDispenser-->>ATM: Success
ATM-->>Customer: Cash + Receipt
Balance Inquiry
Insert Card
↓
Authenticate
↓
Select Balance
↓
Display Balance
Deposit Flow
flowchart LR
USER["User Inserts Cash"]
VALIDATION["Cash Validation Module"]
BANK["Bank Account Service"]
LEDGER["Ledger Update System"]
PRINT["Receipt Generator"]
USER --> VALIDATION --> BANK --> LEDGER --> PRINT
Fund Transfer Flow
flowchart LR
SOURCE["Source Account"]
VALIDATION["Fraud + Balance Validation"]
DEST["Destination Account"]
TRANSFER["Ledger Transfer Engine"]
CONFIRM["Transaction Confirmation"]
SOURCE --> VALIDATION --> DEST --> TRANSFER --> CONFIRM
ATM Session Lifecycle
flowchart LR
IDLE["Idle State"]
CARD["Card Inserted"]
AUTH["Authentication"]
TXN["Transaction Processing"]
EJECT["Card Ejection"]
IDLE --> CARD --> AUTH --> TXN --> EJECT --> IDLE
Transaction Types
Cash Withdrawal
Cash Deposit
Balance Inquiry
Fund Transfer
PIN Change
Mini Statement
ATM States
Idle
Busy
Out of Service
Maintenance
Cash Inventory
Cash dispenser maintains:
$10 Notes
$20 Notes
$50 Notes
$100 Notes
The ATM should calculate the optimal combination of notes.
Cash Dispensing Algorithm
Example:
Withdrawal:
$280
↓
2 × $100
1 × $50
1 × $20
1 × $10
The algorithm should minimize the number of notes while respecting inventory constraints.
Security Features
The ATM should support:
- PIN Encryption
- HTTPS/TLS Communication
- Card Validation
- Session Timeout
- Card Blocking
- Daily Withdrawal Limit
- Fraud Detection
- Failed Login Tracking
Authentication
flowchart LR
CARD["ATM Card Inserted"]
AUTH["PIN Authentication Service"]
SERVER["Bank Core Server"]
OK["Transaction Approved"]
FAIL["Transaction Failed"]
CARD --> AUTH --> SERVER
SERVER --> OK
SERVER --> FAIL
Design Patterns
Singleton
ATM Configuration
Factory Pattern
Transaction Factory
Creates:
- Withdrawal
- Deposit
- Transfer
- Balance Inquiry
Strategy Pattern
Cash Dispensing Strategy
Examples:
- Minimum Notes
- Balanced Note Usage
State Pattern
ATM State
Idle → Busy → Maintenance
Command Pattern
Each transaction acts as a command.
Examples:
- WithdrawCommand
- DepositCommand
- TransferCommand
SOLID Principles
SRP
Each transaction has one responsibility.
OCP
New transaction types can be added without modifying existing ones.
LSP
Every transaction behaves as a Transaction.
ISP
Separate interfaces:
- Authentication
- Cash Dispensing
- Receipt Printing
DIP
ATM depends on interfaces instead of concrete implementations.
Concurrency
Multiple ATMs may access the same account simultaneously.
Challenges:
- Double Withdrawal
- Race Conditions
- Balance Mismatch
Solutions:
- Database Transactions
- Optimistic Locking
- Pessimistic Locking
- Distributed Locks
Database Design
Tables:
Customer
Account
ATM_Card
Transaction
ATM
Cash_Inventory
Spring Boot Layers
flowchart LR
Controller
-->
Service
-->
Repository
-->
Database
REST APIs
POST /authenticate
POST /withdraw
POST /deposit
POST /transfer
GET /balance
GET /statement
POST /change-pin
Enterprise Architecture
flowchart TD
ATM["ATM Terminal"]
GATEWAY["API Gateway"]
AUTH["Auth Service (PIN + Card Validation)"]
TRANSACTION["Transaction Orchestrator"]
ACCOUNT["Account Service"]
NOTIFICATION["Notification Service"]
FRAUD["Fraud Detection Service"]
POSTGRES["PostgreSQL Database"]
KAFKA["Event Streaming (Kafka)"]
CACHE["Redis Cache"]
ATM --> GATEWAY
GATEWAY --> AUTH
GATEWAY --> TRANSACTION
TRANSACTION --> ACCOUNT
TRANSACTION --> NOTIFICATION
TRANSACTION --> FRAUD
TRANSACTION --> POSTGRES
TRANSACTION --> KAFKA
TRANSACTION --> CACHE
Kafka events:
- CashWithdrawn
- DepositCompleted
- TransferCompleted
- PINChanged
- CardBlocked
Redis:
- Session Cache
- Daily Withdrawal Limits
- Temporary Authentication Tokens
Scaling Considerations
Large banking networks support:
- Thousands of ATMs
- Millions of Customers
- Real-Time Transactions
- Multiple Data Centers
Scaling techniques:
- Read Replicas
- Redis Cache
- Kafka
- Horizontal Scaling
- Load Balancers
- Active-Active Deployment
Future Enhancements
Possible features:
- NFC Cardless Withdrawal
- QR Code Withdrawal
- Face Authentication
- Voice Assistance
- Multi-Currency Support
- AI Fraud Detection
- Mobile OTP Verification
- Biometric Authentication
- Contactless Payments
- Cash Recycling
Common Mistakes
❌ Mixing UI logic with business logic.
❌ Ignoring transaction rollback.
❌ No concurrency handling.
❌ No session timeout.
❌ Hardcoded cash dispensing algorithm.
❌ No audit logging.
❌ No fraud detection.
Interview Questions
- How would you prevent double withdrawal?
- How would you implement cash dispensing?
- How do ATMs communicate with the bank?
- Which design patterns are useful?
- How would you calculate note combinations?
- How would you support multiple account types?
- How would you secure PIN verification?
- How would you scale ATM services?
- How would you implement transaction rollback?
- How would you support cardless ATM withdrawals?
Summary
The ATM System is an excellent LLD problem because it combines financial transactions, hardware integration, security, concurrency, and scalable enterprise architecture.
A production-ready implementation typically includes:
- Rich domain models
- Layered Spring Boot architecture
- SOLID principles
- Factory, Strategy, State, Singleton, and Command patterns
- Secure authentication
- Transaction-safe processing
- Cash inventory management
- REST APIs
- Redis for session management
- Kafka for event publishing
- Strong concurrency control
Mastering this design prepares you for more advanced financial system designs such as Core Banking, Payment Gateway, UPI Platform, Credit Card Processing, Wallet Systems, and Digital Banking Platforms, where transaction consistency, security, and reliability are critical.