Safeguard
Developer Tools•

Why should a webhook endpoint answer in seconds and queue the work?

Return a 2xx quickly and process later from a queue. Slow handlers trigger timeouts, retries and duplicates, and can get your endpoint disabled.

Safeguard Security Team
4 min read

Because providers judge delivery by how fast you answer. If your handler does slow work before replying, the provider sees a timeout, retries, and sends duplicates. Verify the signature, save the event, return 2xx, and do the real work from a queue.

The timing rules providers publish

Two examples, both from public documentation:

  • A messaging platform's events API expects an HTTP 2xx response within three seconds. If you miss that, the delivery counts as failed and it retries three times. It recommends responding with 200 as soon as you can and using a queue to handle events after they are received.
  • A payment provider says your endpoint must return a successful status quickly, before any complex logic that could cause a timeout. Its example is that you must return a 200 before updating an invoice as paid in your accounting system.

Both say the same thing in different words: acknowledge first, work second.

What goes wrong with slow handlers

  1. The handler calls three other services, one is slow, the request times out.
  2. The provider retries. Now two copies run, or one runs while the first is still going.
  3. A duplicate email, a double fulfilment, or a half updated record results.
  4. Failure counts climb. On the messaging platform, a very low success rate can lead to the app being temporarily disabled for apps above a volume threshold.

None of this is a security bug on its own. It becomes one when a duplicate triggers a refund twice, or when failed deliveries hide an attack in the noise.

The minimal safe handler

StepDoDo not
1Read the raw bodyParse and re-serialize it first
2Verify signature and timestampSkip verification in a hurry
3Insert the event ID into a table with a unique keyProcess before recording
4Enqueue a job with the event IDCall downstream APIs inline
5Return 2xxReturn 200 only after the job finishes

If step 3 finds the ID already present, return 2xx anyway. The provider only needs to know you have it.

What to put on the queue

Put the event ID, not a copy of sensitive data. The worker can load the stored event. This keeps secrets and personal data out of queue logs and makes retries cheap. Give the queue a dead letter destination and an alert, so a poison event is noticed rather than looping. Related reading: how scan jobs should retry, back off and dead letter.

What if your queue is down?

Then do not return 2xx. Return a 5xx so the provider retries later, and alert. Acknowledging an event you could not store is worse than a retry, because the event is lost. If your storage is healthy but processing is stuck, you can still acknowledge, since the event is safe.

Capacity and abuse

A fast endpoint is also a cheaper target. Signature checks before any database work mean unauthenticated traffic costs you little. Add rate limits at the edge, and keep the endpoint path boring and unguessable only as a bonus, never as the control.

Quick check

What status should I return for a duplicate event?

A 2xx. The event is already stored, so the provider can stop retrying.

Should I return 200 before verifying the signature?

No. Verify first, then acknowledge. Verification is quick, and acknowledging unverified requests invites forged traffic into your queue.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.