
You don't know how to set up webhooks.
- Sahil Shukla
- Dev ops
- August 7, 2026
Table of Contents
Your webhooks should never touch your backend server directly. Why? Because providers are obtuse, digging through logs sucks, and you can’t replay events. Most providers don’t allow you to see sent-over payloads, replay events, or see what your web server responded with (not that it should be anything but 200 OK).
But most importantly, routing webhooks through an event queue decouples ingestion from heavy processing, protects your infrastructure from traffic spikes, and prevents data loss if your server goes down.
graph TD
%% Styles
classDef nodeStyle fill:#f8f9fa,stroke:#6c757d,stroke-width:1px,color:#212529,border-radius:8px;
classDef blueQ fill:#3182ce,stroke:#fff,stroke-width:2px,color:#fff,border-radius:8px;
classDef redQ fill:#e53e3e,stroke:#fff,stroke-width:2px,color:#fff,border-radius:8px;
classDef greenDB fill:#48bb78,stroke:#fff,stroke-width:2px,color:#fff,border-radius:8px;
%% Nodes
Stripe["Stripe
(Webhook)"]:::nodeStyle
API_GW["API Gateway"]:::nodeStyle
SQS_MAIN[("SQS Main Queue")]:::blueQ
SQS_DLQ[("SQS DLQ")]:::redQ
BW["Backend Worker"]:::nodeStyle
DB_Success[("DB")]:::greenDB
Admin["Admin
(Manual Redrive)"]:::nodeStyle
%% Flow
Stripe -- "1. Webhook" --> API_GW
API_GW -- "2. 200 OK Ack" --> Stripe
API_GW -- "3. Publish Event" --> SQS_MAIN
SQS_MAIN -- "4. Message Available" --> BW
BW -- "Success" --> DB_Success
DB_Success -- "5. Explicit ACK & Delete" --> SQS_MAIN
BW -- "Failure" --> SQS_DLQ
Admin -- "6. Redrive" --> SQS_DLQ
SQS_DLQ -- "7. Push back to Main Q" --> SQS_MAIN
%% Edge Styling
linkStyle 0,1,2,3 stroke:#6c757d,stroke-width:1.5px;
linkStyle 4 stroke:#48bb78,stroke-width:1.5px;
linkStyle 5 stroke:#e53e3e,stroke-width:1.5px;
linkStyle 6,7 stroke:#e53e3e,stroke-width:1.5px,stroke-dasharray: 5 5;
Providers Suck
Most providers, regardless of how dev-centric they are, suck, and so does their retry policy. Stripe, Razorpay, Atlassian—all have pretty much the same modus operandi. If your server responds with anything other than 200 OK, it’s considered a failed delivery. Failed delivery is often handled with an immediate retry or an exponential backoff.
After n failed deliveries, they suspend your endpoints. Moreover, they don’t keep a log of all the payloads they sent over. You can’t see the shape or values of the object. There’s no explicit retry button anywhere, so once you lose a bunch of events, the only way for you to get the data back is either to make a GET call to fetch the latest details of the object in your DB, or you write up a nice little email to your provider begging them to redrive events.
Performance and Scaling
You don’t want the success of your platform to be its demise. Say you work at a fintech and are having a usage spike. Your DB and servers are already getting hammered by your users, and each payment made is another webhook received. If these webhooks are coming directly to the server and being processed synchronously, you’ve just doubled your load.
Worse, if your server drops a failed transaction webhook because it ran out of threads, those funds stay locked in a processing state. Your ledger is now out of sync because your backend was too busy to listen.
It is smarter to offload your events to a Q, pick your poison (and I really mean poison). Your system can poll for a set chunk size, spawn threads, and achieve the same results without causing the dreaded 503 or corrupting user balances.
DLQ
Something I find absolutely hilarious is that you create a DLQ before you create the actual Queue. It is such a great allegory for the DLQ itself. If your backend fails to process the task, you can just move it to the DLQ and redrive it later. It’s kept safe with a set retention policy.
Note: A DLQ is pretty much useless if no one is watching it. ALWAYS implement alerts whenever the DLQ is fed.
When is this approach useless?
Anything that is low stakes. You don’t want this heavy lifting if you’re building something that is not mission critical or when you’re building MVPs.
Summary
Stop consuming webhooks directly. Spend the time and do the work required, because everyone knows the backlog is rarely picked up. It’s the junk drawer where you pile up tasks that you’ll never do just because it eases your conscience. Good luck!