𝗧𝗵𝗲 𝗧𝗿𝗮𝗽 𝗜𝗻 𝗕𝗮𝗰𝗸𝗲𝗻𝗱 𝗧𝘂𝘁𝗼𝗿𝗶𝗮𝗹𝘀

Tutorials show you a simple process. Receive a webhook. Update the database. Return a 200 OK.

Your code works in testing. You push it to production. Then you see duplicate records in your database. Users get credited twice. Data entries pile up.

Tutorials ignore the reality of network failure.

The Problem: Unreliable Networks Networks fail. Your server might process data slowly. A DNS error might stop your 200 OK response from reaching the sender.

When a service does not get your confirmation, it retries. It sends the same webhook again. If your code accepts every request, you create duplicates.

The Solution: Idempotency Idempotency means making multiple identical requests has the same effect as a single request.

Think of an elevator button. Pressing the button for floor 5 once tells the elevator where to go. Pressing it ten times does not send the elevator to floor 50. The result stays the same.

Your webhook must act like that button.

How to Fix It Follow these steps to build safe webhooks:

  • Find the unique ID of the event.
  • Check your database for that ID before you do anything.
  • If the ID exists, stop. Return a 200 OK so the sender stops retrying.
  • If the ID is new, process the data.
  • Save the event ID to your database immediately.

Example Logic in Node.js:

const eventId = req.body.event_id;

const existingEvent = await db.processedEvents.findUnique({ where: { id: eventId } });

if (existingEvent) { return res.status(200).send('Already processed'); }

await updateUserData(req.body.data); await db.processedEvents.create({ data: { id: eventId } });

return res.status(200).send('Success');

Building systems for perfect conditions is easy. Building systems for failure is real engineering.

Have you dealt with duplicate data from retries? How do you handle idempotency?

Source: https://dev.to/anubhavg23/the-hidden-trap-in-backend-tutorials-why-your-webhooks-are-creating-duplicate-data-and-how-to-fix-dba