Design a Vending Machine
Design a vending machine system with state machine modeling, inventory management, payment handling, and remote monitoring.
Quick answer: Design a Vending Machine
Design a Vending Machine is covered here as a practical system design interview problem. Design a vending machine system with state machine modeling, inventory management, payment handling, and remote monitoring. Use it to practice requirements, APIs, storage choices, scaling bottlenecks, data consistency, observability, and failure handling for a easy interview round.
Focus on the problem being solved, the main design choice, the failure mode, and the tradeoff you would defend in front of a senior engineer. This page is part of the DosiBridge system design knowledge graph, so it links related concepts, interview problems, tradeoffs, and references instead of leaving the topic isolated.
Problem Statement
Design a vending machine system that manages inventory, processes multiple payment methods, dispenses products via a state machine, and supports remote monitoring across a fleet of machines. The design should cover both the embedded software on the machine and the cloud backend for fleet management.
Requirements
Functional
- Accept payment via coins, bills, credit card, and mobile pay (NFC)
- Display available products with prices; gray out sold-out items
- Dispense selected product and return correct change
- Remote inventory monitoring and restocking alerts for operators
Non-Functional
- Reliability: Must dispense correctly or refund -- no lost money
- Offline resilience: Machine operates for cash transactions even if network is down
- Latency: Product dispensed within 3 seconds of confirmed payment
- Scale: Fleet of 50,000 machines reporting to a central backend
Core Architecture
-
State Machine Controller -- The core on-machine logic. States: IDLE -> ACCEPTING_PAYMENT -> PRODUCT_SELECTED -> DISPENSING -> RETURNING_CHANGE -> IDLE. Transitions are triggered by hardware events (coin inserted, button pressed, product dropped). Invalid transitions (e.g., selecting product before payment) are rejected.
-
Payment Processor -- On-machine module that tracks inserted amount for cash, or communicates with card terminal for electronic payments. Validates that the accumulated amount >= product price before allowing dispensing. For electronic payments, calls the gateway with a timeout and rolls back on failure.
-
Inventory Manager -- Tracks quantity per slot. Decrements on successful dispense. When a product reaches a threshold (e.g., 2 remaining), sends a restocking alert to the cloud backend. Persists inventory state to local flash storage to survive power loss.
- Fleet Management Backend -- Cloud service receiving heartbeats and inventory telemetry from all machines via MQTT. Provides a dashboard for operators showing real-time stock levels, revenue, and machine health. Triggers restocking routes and technician dispatch.
Database Choice
On-machine: Embedded SQLite for local inventory, transaction logs, and state recovery after power loss. Cloud backend: PostgreSQL for machine registry, operator accounts, and restocking schedules. TimescaleDB (Postgres extension) for time-series telemetry (temperature, sales events, error logs). Redis for real-time fleet dashboards aggregating machine status.
Key API Endpoints
POST /api/v1/machines/\{machine_id\}/telemetry
-> Body: \{ inventory: [\{ slot: "A1", product: "Cola", qty: 3 \}], revenue_today: 142.50, temp_c: 4.2 \}
GET /api/v1/machines/\{machine_id\}/status
-> Returns: \{ online: true, last_heartbeat: "...", low_stock_slots: ["B3", "C1"] \}
POST /api/v1/machines/\{machine_id\}/restock
-> Body: \{ slots: [\{ slot: "A1", qty_added: 10 \}], technician_id: "T-42" \}
Scaling Insight
Use MQTT with a fan-in broker (e.g., EMQX) for machine-to-cloud communication instead of HTTP polling. Each machine maintains a persistent MQTT connection, sending telemetry every 60 seconds and receiving config pushes (price changes, new products) instantly. MQTT handles 50K concurrent connections easily on a single broker and uses <1 KB per heartbeat, keeping cellular data costs low for machines on mobile networks.
Key Tradeoffs
| Decision | Option A | Option B | Chosen |
|---|---|---|---|
| Communication | HTTP polling | MQTT persistent connection | MQTT -- lower bandwidth, real-time push capability, better for cellular |
| Payment failure | Block until gateway responds | Timeout and refund after 10s | Timeout -- prevents machine from locking up on network issues |
| Inventory sync | Real-time per transaction | Batch every 5 minutes | Batch -- reduces cellular costs, acceptable delay for restocking decisions |
Original DosiBridge notes for Design a Vending Machine
This section is written specifically for this page, not copied from a general system-design checklist. The useful way to study Design a Vending Machine is to connect the concept to a production service where growth exposes the first weak assumption in the original design. That framing changes the design discussion from definitions to operating choices.
What makes this topic distinct
- Core Entity: For Design a Vending Machine, decide the core entity before choosing tools; otherwise the design looks clean but fails when vending changes.
- Read/Write Path: For Design a Vending Machine, decide the read/write path before choosing tools; otherwise the design looks clean but fails when machine changes.
- Contention Point: For Design a Vending Machine, decide the contention point before choosing tools; otherwise the design looks clean but fails when vending changes.
- Abuse Path: For Design a Vending Machine, decide the abuse path before choosing tools; otherwise the design looks clean but fails when machine changes.
- Recovery Workflow: For Design a Vending Machine, decide the recovery workflow before choosing tools; otherwise the design looks clean but fails when vending changes.
Design a Vending Machine correctness boundary
For this problem, separate the user-visible action from background work. The correctness boundary is the smallest state transition that must not be duplicated, lost, or reordered. Naming that boundary makes the solution more original than a stock API/database/cache template.
Design a Vending Machine scaling bottleneck
The first bottleneck should be described in the language of this system: a hot timeline, a contested seat, a busy wallet ledger, a media-processing queue, or a search index update delay. That bottleneck decides which component deserves the deepest interview discussion.
Production review question
If Design a Vending Machine suddenly receives 10x traffic, which entity becomes contested first, and what queue, lock, shard, or cache protects that entity without hiding correctness bugs?
Practical metric to track
Track vending-machine health as a named dashboard or review item: combine one user-facing metric, one saturation metric, and one correctness metric. For Design a Vending Machine, this keeps the discussion grounded in behavior that can be measured after deployment instead of generic advice that sounds good in an interview but never gets verified.