In short
Networks fail at the worst moment. A payment request times out and the app retries. Did the user just pay twice? Idempotency is how good backends make retries safe.
A request is idempotent if making it multiple times has the same effect as making it once — a critical property for safely retrying failed requests, e.g. after a network timeout.

Think of it like this
Tapping Pay twice at the chai stall
The UPI screen hangs, so you tap Pay again. Panic! But the app reused the same transaction reference, so the bank sees one payment, not two. The chaiwala gets his 20 rupees once. Idempotency means: same request again, same result, no double effect.
Watch it happen
A retry that doesn't charge twice
POST /pay key=k7
1/6The app sends the payment with an Idempotency-Key header it generated for this one tap.
The big ideas
What you need to know
Same request, same effect
An operation is idempotent if doing it twice leaves things exactly as doing it once.
Which methods are
GET, PUT and DELETE are idempotent by design. POST is not, so a repeated POST can create duplicates.
Idempotency keys
The client sends a unique key with each action. The server stores key plus result and replays it on retries.
Unique constraints as backup
A unique index, for example on order_ref, stops duplicates even if two retries race each other.
See it in code
Walk through the code
1const seen = new Map(); // use Redis or a DB table in production2 3app.post("/payments", async (req, res) => {4 const key = req.get("Idempotency-Key");5 if (!key) return res.status(400).json({ error: "Idempotency-Key header required" });6 7 if (seen.has(key)) return res.status(201).json(seen.get(key));8 9 const payment = await charge(req.body.amount); // your payment logic10 seen.set(key, payment);11 res.status(201).json(payment);12});1/3Demand a key, so every payment can be recognised if it comes again.
The client creates the key once per action, say with crypto.randomUUID(), and reuses it on retries. Real systems also lock the key so parallel retries can't both charge.
Save yourself the pain
Common mistakes
Oops
Automatically retrying POST requests with no key.
Do this instead
Only auto-retry idempotent requests, or add an Idempotency-Key so the server can spot duplicates.
Oops
Generating a fresh key on every retry.
Do this instead
A new key looks like a brand-new payment. Create the key once per user action and keep it for all retries.
Your mission
Make an endpoint retry-safe
Quick check
Which of these requests is idempotent?
Go deeper
- 1Identify which HTTP methods are idempotent by spec (GET, PUT, DELETE) and which aren't (POST).
- 2Design an idempotency-key system for a payment endpoint to prevent double-charging.
- 3Understand why retries without idempotency can cause duplicate data or charges.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.