How to Rate Limit a Webhook Endpoint
Rate limit a webhook after verifying its signature, and return 429 with Retry-After so a well-behaved sender backs off.
Apply a limiter keyed by source or app id once the signature is verified. Return 429 with a Retry-After header so the sender retries later instead of hammering.
Steps
- Verify the signature first, so unauthenticated traffic is dropped early.
- Apply a token-bucket limit keyed by app or source.
- Return 429 with a
Retry-Afterheader when the limit is exceeded.
Middleware
handler.js
function limit(req, res, next) {
const key = req.headers['x-github-hook-installation-target-id'] || req.ip;
if (!bucket.take(key)) {
res.set('Retry-After', '30');
return res.status(429).end();
}
next();
}Gotchas
- A 429 is treated as a failure, so the sender will retry; keep dedupe in place.
- Rate limit after signature checks so a limiter is not spent on forged traffic.