You run the platform team at an Indian UPI payments app (a TPAP) with 90 million monthly users, routing payments through three sponsor PSP banks to the NPCI UPI switch. A normal evening peak is about 3,000 payments per second; during last year's biggest sale day it hit 22,000 for forty minutes, two large issuer banks started timing out, app retries doubled the load, and support received 60,000 'money debited but payment failed' tickets. Marketing expects 30,000 payments per second this season.
The interviewer asks“Design the transaction platform for this year's festival peak. Walk me through the request flow, how you guarantee a payment is submitted exactly once, and how you stop one slow bank from taking the whole app down.”
I treat every payment as a state machine keyed by an idempotency key and a single UPI transaction ID, and a timeout is never a failure: it becomes PENDING and is resolved by status check, never by re-sending. The synchronous path is kept thin and protected by admission control, per-PSP and per-issuer-bank bulkheads and circuit breakers, while everything that can be asynchronous goes through an outbox into Kafka. The real ceiling is the banks, so capacity math starts from contracted PSP TPS and issuer health, with headroom and a degradation ladder for the rest. Every SLI is sliced per bank and per response-code class, because one sick bank hides inside a healthy average.
A free account unlocks the rest of it, and saves your progress across every track.