Webhooks & Events

Responding to Webhooks Quickly

Providers give you a short window to reply. Answer fast and do the slow work afterwards.

What you'll learn

  • Explain the provider timeout and why it exists
  • Separate acknowledgement from processing cleanly
  • Hand heavy work to a queue or background worker
  • Avoid the common causes of slow handlers

5 min read

The timeout clock

When a provider delivers a webhook, it waits only a short time for your 2xx reply — often just a handful of seconds before it gives up. If you do not answer within that window, the provider treats the delivery as failed and schedules a retry, even if your handler eventually went on to finish the work perfectly well. From the provider's side, a slow answer is indistinguishable from no answer at all.

This timeout exists because the provider cannot afford to hold connections open indefinitely; it has a great many endpoints to serve and finite resources to do it with. The practical consequence for you is simple but important: acknowledge quickly, always. A slow handler does not merely delay your own processing — it actively manufactures duplicate deliveries through needless retries, multiplying your work.

Acknowledge, then process

The reliable pattern is to do the absolute minimum inside the request itself — verify the signature and persist or enqueue the event — and then return immediately. The real processing happens afterwards, comfortably outside the provider's timeout window, where it can take as long as it genuinely needs without any clock ticking against it.

function handle(request) {
  if (!verify(request)) return respond(401);
  queue.enqueue(request.body); // fast, durable
  return respond(202);         // acknowledge now
}

A 202 Accepted says, in effect, I have the event and I will deal with it, which is exactly the contract you want to offer the provider. It promises nothing about completion, only safe receipt, and that is all the provider needs to hear.

Offload the heavy lifting

Anything slow — calling third-party services, sending emails, running complex database work — belongs in a background worker fed by a durable queue, not in the request handler. The queue does two valuable jobs at once: it decouples the work from the inbound request so the response stays fast, and it gives you a natural place to retry on your own terms if that processing later fails.

This is the same acknowledge-first design described in designing a webhook receiver, viewed through the lens of speed. Persisting the event before you reply means that a crash partway through processing never loses it; the worker simply picks the event up again from the queue and tries once more, with no involvement from the provider.

Common speed traps

Slow handlers almost always come from doing too much inline. Synchronous calls out to other APIs, heavy database queries, and parsing of large payloads on the request path each add latency, and together they can easily push you past the timeout when traffic spikes. The remedy is consistent: move every one of those off the hot path and into the background where it belongs.

Also keep a close eye on cold starts and connection setup, which can silently eat your entire time budget on the very first request after a quiet period. Keep the endpoint lean and actually measure its response time under load rather than assuming it is fast. The provider's specific timeout value is noted in the API documentation so you can design against the real number.

Key takeaways

  • Providers expect a 2xx within a few seconds or they retry
  • Verify and enqueue, then acknowledge before processing begins
  • Push slow work to a background worker via a durable queue
  • Avoid synchronous third-party calls on the request path

FAQ

How fast do I need to respond to a webhook?

Within the provider's timeout, typically a few seconds. The safest approach is to enqueue the event and return immediately, regardless of how long processing takes.

What does a 202 response mean to the provider?

It signals that you have accepted the event for processing. Like any 2xx, it tells the provider not to retry, even though the actual work happens afterwards.

Why is my handler timing out?

Usually because it does heavy work inline — external API calls, big queries, or large parsing. Move that work to a background worker so the request returns quickly.

Integrate with Merion

Ready to build?

Read the API reference, grab the OpenAPI spec, and ship a resilient integration.