System Design: UPI Payments App (WalnutPe: Device Binding, Pending Payments, 10,000 Payments a Second)
Goal: Design our own UPI payments app, like PhonePe or Google Pay. We call it WalnutPe. UPI is India's system for instant payments from one bank account to another. You scan a shop's code, type a secret number, and the money moves in about two seconds.
We build the app and its backend, for 400 million users and up to 10,000 payments a second.
WalnutPe is not Walnut Pay, the shop gateway in our payment gateway post, or Walnut Switch, the network in the middle in our UPI platform post. Section 1.3 explains.
1. What We Are Building
๐ Premium section
2. Requirements and Scale
2.1 What the System Must Do
Each FR (functional requirement) is something the system must do.
| ID | Requirement |
|---|---|
| FR-01 | Sign up, tie the app to this phone and SIM, find the user's bank accounts, and set a UPI PIN (section 6). |
| FR-02 | Give each user a UPI ID on one partner bank, with an optional second on another (section 9). |
| FR-03 | Pay by scanning a code, from another app's "Pay with UPI" button, or to a UPI ID, phone number or contact (section 7). |
| FR-04 | Show the payee's name as their bank has it, before the PIN screen (section 3.2). |
| FR-05 | Show each payment as success, failed or pending, and update it when the final answer comes (section 8). |
| FR-06 | Show the balance, mostly from the balance that comes back with each payment. |
| FR-07 | Show payment history, newest first, with search (section 11). |
| FR-08 | Notify the payer, and the payee if they also use WalnutPe. |
| FR-09 | Approve, pause and cancel automatic payments like Priya's โน399 plan (section 12). |
| FR-10 | Offer small PIN-free payments and payments by trusted family members (section 12). |
| FR-11 | Raise and track a complaint about a payment inside the app (section 13). |
| FR-12 | Warn about, slow down or stop payments that look like fraud (section 10). |
| FR-13 | Add or remove bank accounts, change or reset the PIN, move to a new phone. |
2.2 How Well It Must Do It
A ms is a millisecond, a thousandth of a second. p50 is the time that half of all requests beat. p99 is the time that 99 of every 100 beat, so it shows the slow tail.
Each NFR (non-functional requirement) is a target we set and measure every month.
- NFR-01. Our part is fast. Our backend adds at most 300 ms at p99. The PSP bank, NPCI and the two banks have up to 15 s.
- NFR-02. Feels instant. From confirming the PIN to the result, p50 under 3 s. After 15 s with no answer, the app shows "Pending. Your money is safe."
- NFR-03. The pay path stays up. 99.99% a month for our part, about 4 minutes of failure. On a very busy day, history and rewards (scratch cards and cashback) are the first to turn off.
- NFR-04. Never pay twice because of us. A retry never becomes a second payment, and we never show "failed" while money may have left.
- NFR-05. Obey NPCI's limits. Status checks, balance checks and account lookups stay in budget. Calls that no person tapped for stay out of peak hours, except status checks (section 3.6).
- NFR-06. Keep secrets. The PIN never reaches our servers readable. Payment data stays in India. IDs, phone and account numbers are partly hidden on screen.
- NFR-07. Contain bank outages. When one partner bank is down, only its users are hit, and they can switch to a second UPI ID.
2.3 The Numbers
These are planning numbers. Section 15 has the full sizing.
Payments. WalnutPe handles 25% of UPI volume. That is under NPCI's rule that no app may carry more than 30% of UPI volume (section 20.4).
- Per day. 25% of 802 million is about 200 million.
- Average. 200,000,000 / 86,400 seconds is about 2,300 a second.
- Evening peak. About 3 times that, about 7,000 a second.
- Design target. Salary days and festival evenings add more. We design for 10,000 a second.
Users. 400 million registered, 150 million active in a month.
Calls per payment. Four requests reach our API servers: resolve the payee, create, submit, and the PSP bank's result callback (section 4). A callback is a message the PSP bank sends back to us with the result.
Our partner banks get one name check (asking whose UPI ID this is, section 3.2) and one pay request. At the design peak that is about 10,000 of each a second.
Status checks. Some answers go missing, so we ask later (section 3.6). Our simulation needed 19 to 22 checks per 1,000 payments for the two schedules in section 8.4. That is about 190 to 220 a second at the design peak (section 23).
History. About 1.3 rows per payment (payer, plus payee if on WalnutPe): 260 million rows, about 78 GB a day. Money paid to our users from other apps adds about 180 million more rows (section 15.6).
Notifications. One push notification (an alert on the phone) per history row: about 440 million a day, with credits from other apps. At the design peak that is about 22,000 a second. Google's default limit is 10,000 a second per project (a project is one app account at Google), so we need over twice that (section 11.6).
Fraud counters (small running counts per user, such as payments in the last 10 minutes; section 10). About 580 bytes per active user in our test of the section 10.4 code, so about 87 GB for 150 million users.
Phone bindings (tying the app to one phone and SIM, section 3.3). 2 million a day, from new phones, SIM changes and reinstalls.
2.4 Out of Scope
- The UPI switch. NPCI's centre is our UPI platform post.
- The merchant side. That is the gateway post.
- Lending and the bank's core system. Banks decide credit lines and keep balances. We only show them.
- Fees. The MDR (merchant discount rate), the fee a shop pays per payment, is still zero for UPI after a planned 0.4% fee was put off on 13 October 2026.
3. How UPI Works
๐ Premium section
4. The API and Data
๐ Premium section
5. High-Level Design
๐ Premium section
6. Deep Dive: Sign-up, Device Binding and the PIN
๐ Premium section
7. Deep Dive: Making a Payment
๐ Premium section
8. Deep Dive: Pending Payments and Status Checks
๐ Premium section
9. Deep Dive: Several PSP Banks
๐ Premium section
10. Deep Dive: Fraud and Limits
๐ Premium section
11. Deep Dive: Transaction History and Notifications
๐ Premium section
12. Deep Dive: AutoPay, UPI Lite and Other Payment Types
๐ Premium section
13. Deep Dive: Disputes and Refunds (Payer's Side)
๐ Premium section
14. Deep Dive: Peaks and Bad Days
๐ Premium section
15. Capacity
๐ Premium section
16. What Happens When Each Part Goes Down
๐ Premium section
17. Bottlenecks
๐ Premium section
18. Regions and Data
๐ Premium section
19. Security and Privacy
๐ Premium section
20. Running It
๐ Premium section
21. Trade-offs
๐ Premium section
22. In the Interview
๐ Premium section
23. How We Measured
๐ Premium section
24. Further Reading
๐ Premium section
Explore the Technologies
๐ Premium section