HomeResourcesCase study
Case study

Razorpay's Coupons Were Delaying Your OTP

By The SDL team·3 min read·Updated Sep 16, 2026

A queue decouples producers from flaky providers. But a plain FIFO queue lets a marketing blast starve a payment OTP — so add priority.

Razorpay's notification system treated every message the same. That sounds fair until you realize it meant a marketing blast could delay the one-time password someone needed to complete a payment.

At peak, MySQL became the bottleneck for guaranteed-delivery notifications, and — worse than slow — the system was egalitarian: a transactional OTP and a promotional SMS sat in the same line, so low-value bulk traffic could starve high-value transactional traffic exactly when it mattered most.

Plain English

When one part of your system creates work for another (here: 'send this notification'), wiring them together directly means a slowdown in sending backs up into the thing that requested it. The fix is a queue in between: the producer drops a message and moves on; workers pull from the queue at their own pace. The two sides are now decoupled — a slow SMS provider no longer freezes your payment flow.

But a single queue has a flaw: it's first-come-first-served. Put a million marketing messages in front of one critical OTP, and the OTP waits behind the million. You need priority.

Now the engineering

Razorpay moved to SQS-based decoupling: producers enqueue notifications; a pool of workers (an executor) consumes and dispatches to SMS/email/push providers. This removes MySQL as the throughput chokepoint and lets sending scale independently of the services requesting it.

On top, two essentials. Prioritization: critical transactional notifications (OTPs, payment confirmations) are routed and drained ahead of bulk marketing, so a promotional surge can't delay a payment. And a retry scheduler: because delivery must be guaranteed, failed sends are tracked and retried rather than silently dropped — turning 'best effort' into 'eventually delivered.'

Decouple with a queue — and don’t treat all messages as equal producers critical queue (txn OTP) bulk queue (marketing) workers / executor drain critical first SMS / email / push providers scheduler retries failed sends Old design: MySQL as the buffer + every notification equal → a marketing blast could delay your payment OTP. Unacceptable. Fix: SQS decoupling + priority lanes + a retry scheduler for guaranteed delivery
Decouple, then prioritise. A queue protects the payment flow from slow providers; priority lanes protect the OTP from the marketing blast; the scheduler guarantees delivery.

Worth knowing

This is the same prioritisation instinct as Netflix's load shedding (#7), in a humbler setting: when resources are contended, the system must know which work is valuable. A queue alone gives you decoupling and durability; priority lanes give you the judgment to spend scarce delivery capacity on the OTP, not the coupon. Decoupling without prioritisation just moves the starvation into the queue.

The gap it reveals

'Add a queue' is a common reflex; the gap is knowing what a plain queue does and doesn't buy you. It decouples and (with retries) guarantees delivery — but it's FIFO, so without priority lanes your most important message can wait behind your least important. Recognising that contended notification systems need explicit prioritisation, plus a retry mechanism for guaranteed delivery, is the design-complete view.

In the interview room

"Design a notification service" rewards three moves: a queue to decouple producers from flaky providers, priority tiers so transactional beats promotional, and a retry/scheduler path for guaranteed delivery (with idempotency so retries don't double-send). Volunteering the priority and retry pieces — not just 'use a queue' — is what separates a complete design from a sketch.

The reframe

Decoupling with a queue is the easy, famous half of the answer. The half that separates a working system from a fair one is admitting your messages aren't equal and encoding that truth into the architecture. A system that treats a payment OTP and a coupon identically isn't simple — it's neglecting the most important decision it could make.

A queue buys you breathing room. Priority buys you the right outcome when the room runs out.

Primary source →
Razorpay Engineering — How Razorpay’s Notification Service Handles Increasing Load

Want feedback on your design?

The weekly teardown

One real-world architecture, every week.

How real companies actually built it: the design, the trade-offs, and what to say about it in an interview. Free, and one click to unsubscribe.

Related articles