Duplicate Webhooks
Understand and handle duplicate webhook deliveries.
2 min read
Last updated 31 December 2024
Webhooks may occasionally be delivered more than once. This guide explains why and how to handle it.
Why Duplicates Occur
Technical Causes
| Cause | Description |
|---|---|
| Network timeout | Request succeeded but response lost |
| Retry after error | 5xx error triggered retry |
| System recovery | Webhooks replayed after outage |
| Shopify retries | Shopify resends on failure |
It's By Design
Webhooks are "at least once" delivery:
- Guaranteed to be delivered
- May be delivered multiple times
- Your system should handle duplicates
Handling Duplicates
Idempotency Keys
Use delivery IDs to detect duplicates:
async function handleWebhook(request) {
const deliveryId = request.headers['x-returnmate-delivery-id'];
// Check if already processed
const existing = await db.webhooks.findOne({ deliveryId });
if (existing) {
console.log('Duplicate webhook, skipping');
return { status: 200 };
}
// Process the webhook
await processWebhookPayload(request.body);
// Record as processed
await db.webhooks.insert({ deliveryId, processedAt: new Date() });
return { status: 200 };
}
Database Constraints
Use unique constraints:
- Store webhook delivery IDs
- Use database uniqueness
- Let duplicates fail silently
Shopify Webhook Duplicates
Shopify webhooks can also duplicate:
Common Scenarios
- Order update during high traffic
- App reinstallation
- Webhook endpoint timeout
- Shopify internal retries
Handling Strategy
// For Shopify order webhooks
async function handleOrderWebhook(order) {
const key = `order-${order.id}-${order.updated_at}`;
if (await alreadyProcessed(key)) {
return; // Skip duplicate
}
await processOrder(order);
await markProcessed(key);
}
Monitoring Duplicates
What to Track
- Total webhooks received
- Duplicates detected
- Duplicate rate (should be < 1%)
Alerting
Set alerts if duplicate rate exceeds threshold:
- Normal: < 1%
- Investigate: 1-5%
- Problem: > 5%
Best Practices
- Always implement idempotency
- Store delivery IDs with TTL
- Use database unique constraints
- Monitor duplicate rates
- Log duplicates for debugging
TTL for Delivery IDs
Store delivery IDs for 7-14 days, then purge. Duplicates typically arrive within hours, not weeks.
Related Articles
Was this helpful?
Contact Support