[{"data":1,"prerenderedAt":457},["ShallowReactive",2],{"content-query-QaqjoyChyY":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"layout":10,"crumb":11,"summary":12,"group":13,"order":14,"code":14,"updated":15,"cta":16,"related":24,"faq":43,"body":56,"_type":450,"_id":451,"_source":452,"_file":453,"_stem":454,"_extension":455,"sitemap":456},"/http-errors/429-too-many-requests","http-errors",false,"","429 Too Many Requests: what it means and how to fix it","HTTP 429 Too Many Requests means you hit a rate limit. What causes it, how to read Retry-After, how to back off correctly, and how to stop webhook bursts from causing it.","reference","429 Too Many Requests","You hit a rate limit. Back off, honour Retry-After, or smooth the bursts.","4xx client errors",429,"2026-10-28",{"eyebrow":17,"title":18,"text":19,"to":20,"label":21,"secondaryTo":22,"secondaryLabel":23},"Webhook Relay Throttling","Stop webhook bursts from turning into 429s","Outbound throttling holds incoming webhooks and releases them to your endpoint at a steady rate or a fixed concurrency, oldest first, so nothing is dropped. It's available on every plan, Free included.","/features/throttling/","See throttling","/docs/webhooks/outbound-throttling/","Outbound throttling docs",[25,28,31,34,37,40],{"title":26,"to":27},"503 Service Unavailable","/http-errors/503-service-unavailable/",{"title":29,"to":30},"504 Gateway Timeout","/http-errors/504-gateway-timeout/",{"title":32,"to":33},"Exponential backoff","/glossary/exponential-backoff/",{"title":35,"to":36},"Webhook retries","/glossary/webhook-retries/",{"title":38,"to":39},"502 Bad Gateway","/http-errors/502-bad-gateway/",{"title":41,"to":42},"Webhook retries and idempotency","/blog/webhook-retries-and-idempotency/",[44,47,50,53],{"q":45,"a":46},"What does 429 Too Many Requests mean?","HTTP 429 means the server is rate limiting you: you sent more requests in a time window than it allows. The request wasn't processed. Wait and retry, ideally after the delay the server gives in its Retry-After header.",{"q":48,"a":49},"How long should I wait after a 429?","If the response has a Retry-After header, wait that long: it is either a number of seconds or an HTTP date. If there's no header, retry with exponential backoff and jitter, for example 1s, 2s, 4s, 8s plus a random offset, and cap the number of attempts.",{"q":51,"a":52},"Is 429 a client error or a server error?","It's a 4xx client error: the server is working, but it refuses this request because the client is over its limit. Unlike most 4xx errors, a 429 is meant to be retried later.",{"q":54,"a":55},"Why does my webhook endpoint return 429?","Usually a burst. A provider replays a backlog, a sale or batch job fires thousands of events, or your own rate limiter or API gateway (Cloudflare, AWS API Gateway, nginx limit_req) caps requests per second. Most providers treat 429 as a failed delivery and retry, so the burst comes back again. Throttle delivery to a pace the endpoint can handle instead of raising the limit.",{"type":57,"children":58,"toc":444},"root",[59,87,145,152,213,219,335,341,360,387,393,438],{"type":60,"tag":61,"props":62,"children":63},"element","p",{},[64,77,79,85],{"type":60,"tag":65,"props":66,"children":67},"strong",{},[68,75],{"type":60,"tag":69,"props":70,"children":72},"code",{"className":71},[],[73],{"type":74,"value":11},"text",{"type":74,"value":76}," means the server is rate limiting you: you've sent more requests in a given window than it allows, so it refused this one without processing it.",{"type":74,"value":78}," It isn't a failure of the server. It's a request to slow down, and the response often says exactly how long to wait in a ",{"type":60,"tag":69,"props":80,"children":82},{"className":81},[],[83],{"type":74,"value":84},"Retry-After",{"type":74,"value":86}," header.",{"type":60,"tag":88,"props":89,"children":93},"pre",{"className":90,"code":91,"language":92,"meta":7,"style":7},"language-http shiki shiki-themes github-dark","HTTP/1.1 429 Too Many Requests\nRetry-After: 30\nContent-Type: application/json\n\n{\"error\": \"rate_limited\", \"message\": \"Too many requests, retry in 30 seconds\"}\n","http",[94],{"type":60,"tag":69,"props":95,"children":96},{"__ignoreMap":7},[97,108,117,126,136],{"type":60,"tag":98,"props":99,"children":102},"span",{"class":100,"line":101},"line",1,[103],{"type":60,"tag":98,"props":104,"children":105},{},[106],{"type":74,"value":107},"HTTP/1.1 429 Too Many Requests\n",{"type":60,"tag":98,"props":109,"children":111},{"class":100,"line":110},2,[112],{"type":60,"tag":98,"props":113,"children":114},{},[115],{"type":74,"value":116},"Retry-After: 30\n",{"type":60,"tag":98,"props":118,"children":120},{"class":100,"line":119},3,[121],{"type":60,"tag":98,"props":122,"children":123},{},[124],{"type":74,"value":125},"Content-Type: application/json\n",{"type":60,"tag":98,"props":127,"children":129},{"class":100,"line":128},4,[130],{"type":60,"tag":98,"props":131,"children":133},{"emptyLinePlaceholder":132},true,[134],{"type":74,"value":135},"\n",{"type":60,"tag":98,"props":137,"children":139},{"class":100,"line":138},5,[140],{"type":60,"tag":98,"props":141,"children":142},{},[143],{"type":74,"value":144},"{\"error\": \"rate_limited\", \"message\": \"Too many requests, retry in 30 seconds\"}\n",{"type":60,"tag":146,"props":147,"children":149},"h2",{"id":148},"common-causes",[150],{"type":74,"value":151},"Common causes",{"type":60,"tag":153,"props":154,"children":155},"ul",{},[156,167,193,203],{"type":60,"tag":157,"props":158,"children":159},"li",{},[160,165],{"type":60,"tag":65,"props":161,"children":162},{},[163],{"type":74,"value":164},"An API's rate limit.",{"type":74,"value":166}," GitHub, Stripe, OpenAI, Shopify and most public APIs cap requests per second, minute or hour, per key or per IP.",{"type":60,"tag":157,"props":168,"children":169},{},[170,175,177,183,185,191],{"type":60,"tag":65,"props":171,"children":172},{},[173],{"type":74,"value":174},"Your own gateway or proxy.",{"type":74,"value":176}," Cloudflare rate-limiting rules, AWS API Gateway throttling, nginx ",{"type":60,"tag":69,"props":178,"children":180},{"className":179},[],[181],{"type":74,"value":182},"limit_req",{"type":74,"value":184}," and Kong all answer ",{"type":60,"tag":69,"props":186,"children":188},{"className":187},[],[189],{"type":74,"value":190},"429",{"type":74,"value":192}," when a client goes over a limit.",{"type":60,"tag":157,"props":194,"children":195},{},[196,201],{"type":60,"tag":65,"props":197,"children":198},{},[199],{"type":74,"value":200},"Retry storms.",{"type":74,"value":202}," A client that retries immediately on failure multiplies its own traffic and stays over the limit.",{"type":60,"tag":157,"props":204,"children":205},{},[206,211],{"type":60,"tag":65,"props":207,"children":208},{},[209],{"type":74,"value":210},"Webhook bursts.",{"type":74,"value":212}," A provider replays a backlog or a batch job fires thousands of events at once, and your endpoint (or the API it calls) rate-limits them.",{"type":60,"tag":146,"props":214,"children":216},{"id":215},"how-to-fix-a-429-as-a-client",[217],{"type":74,"value":218},"How to fix a 429 as a client",{"type":60,"tag":220,"props":221,"children":222},"ol",{},[223,248,265,315,325],{"type":60,"tag":157,"props":224,"children":225},{},[226,238,240,246],{"type":60,"tag":65,"props":227,"children":228},{},[229,231,236],{"type":74,"value":230},"Honour ",{"type":60,"tag":69,"props":232,"children":234},{"className":233},[],[235],{"type":74,"value":84},{"type":74,"value":237},".",{"type":74,"value":239}," It's either seconds (",{"type":60,"tag":69,"props":241,"children":243},{"className":242},[],[244],{"type":74,"value":245},"Retry-After: 30",{"type":74,"value":247},") or an HTTP date. Don't send the request again before then.",{"type":60,"tag":157,"props":249,"children":250},{},[251,256,258,264],{"type":60,"tag":65,"props":252,"children":253},{},[254],{"type":74,"value":255},"Back off exponentially with jitter",{"type":74,"value":257}," when there's no header: wait 1s, 2s, 4s, 8s… plus a random offset so many clients don't retry in lockstep. See ",{"type":60,"tag":259,"props":260,"children":261},"a",{"href":33},[262],{"type":74,"value":263},"exponential backoff",{"type":74,"value":237},{"type":60,"tag":157,"props":266,"children":267},{},[268,273,275,281,283,289,291,297,299,305,307,313],{"type":60,"tag":65,"props":269,"children":270},{},[271],{"type":74,"value":272},"Read the rate-limit headers.",{"type":74,"value":274}," Many APIs send ",{"type":60,"tag":69,"props":276,"children":278},{"className":277},[],[279],{"type":74,"value":280},"X-RateLimit-Remaining",{"type":74,"value":282}," and ",{"type":60,"tag":69,"props":284,"children":286},{"className":285},[],[287],{"type":74,"value":288},"X-RateLimit-Reset",{"type":74,"value":290}," (or the standard ",{"type":60,"tag":69,"props":292,"children":294},{"className":293},[],[295],{"type":74,"value":296},"RateLimit",{"type":74,"value":298}," / ",{"type":60,"tag":69,"props":300,"children":302},{"className":301},[],[303],{"type":74,"value":304},"RateLimit-Policy",{"type":74,"value":306}," headers) so you can slow down ",{"type":60,"tag":308,"props":309,"children":310},"em",{},[311],{"type":74,"value":312},"before",{"type":74,"value":314}," you hit 429.",{"type":60,"tag":157,"props":316,"children":317},{},[318,323],{"type":60,"tag":65,"props":319,"children":320},{},[321],{"type":74,"value":322},"Batch and cache.",{"type":74,"value":324}," Fewer, larger requests and cached responses use less of your quota.",{"type":60,"tag":157,"props":326,"children":327},{},[328,333],{"type":60,"tag":65,"props":329,"children":330},{},[331],{"type":74,"value":332},"Ask for a higher limit",{"type":74,"value":334}," if your steady-state traffic is legitimately above it.",{"type":60,"tag":146,"props":336,"children":338},{"id":337},"_429s-on-a-webhook-endpoint",[339],{"type":74,"value":340},"429s on a webhook endpoint",{"type":60,"tag":61,"props":342,"children":343},{},[344,346,351,353,358],{"type":74,"value":345},"When your webhook receiver answers ",{"type":60,"tag":69,"props":347,"children":349},{"className":348},[],[350],{"type":74,"value":190},{"type":74,"value":352},", most providers count it as a failed delivery and ",{"type":60,"tag":65,"props":354,"children":355},{},[356],{"type":74,"value":357},"retry",{"type":74,"value":359},". That's good for durability, but the retries land on an endpoint that's already over its limit. Raising the limit only moves the problem downstream to your database or the API your handler calls.",{"type":60,"tag":61,"props":361,"children":362},{},[363,365,370,372,377,379,385],{"type":74,"value":364},"The usual fix is to ",{"type":60,"tag":65,"props":366,"children":367},{},[368],{"type":74,"value":369},"put a buffer between the sender and your endpoint",{"type":74,"value":371}," and release events at a pace the endpoint can handle. With Webhook Relay ",{"type":60,"tag":259,"props":373,"children":374},{"href":22},[375],{"type":74,"value":376},"outbound throttling",{"type":74,"value":378},", you set a rate (for example 10 requests per second) or a maximum concurrency per destination. A burst of 5,000 events turns into a steady stream, nothing is dropped, and events are delivered oldest first. If the destination still fails, ",{"type":60,"tag":259,"props":380,"children":382},{"href":381},"/features/durable-retries/",[383],{"type":74,"value":384},"durable retries",{"type":74,"value":386}," keep trying with backoff for up to 30 days.",{"type":60,"tag":146,"props":388,"children":390},{"id":389},"when-to-return-429-from-your-own-api",[391],{"type":74,"value":392},"When to return 429 from your own API",{"type":60,"tag":61,"props":394,"children":395},{},[396,398,403,405,411,413,419,421,426,428,436],{"type":74,"value":397},"Return ",{"type":60,"tag":69,"props":399,"children":401},{"className":400},[],[402],{"type":74,"value":190},{"type":74,"value":404}," (not ",{"type":60,"tag":69,"props":406,"children":408},{"className":407},[],[409],{"type":74,"value":410},"503",{"type":74,"value":412}," or ",{"type":60,"tag":69,"props":414,"children":416},{"className":415},[],[417],{"type":74,"value":418},"400",{"type":74,"value":420},") when a specific client is over its quota, and include ",{"type":60,"tag":69,"props":422,"children":424},{"className":423},[],[425],{"type":74,"value":84},{"type":74,"value":427},". Use ",{"type":60,"tag":259,"props":429,"children":430},{"href":27},[431],{"type":60,"tag":69,"props":432,"children":434},{"className":433},[],[435],{"type":74,"value":26},{"type":74,"value":437}," when the whole service is overloaded or down for everyone.",{"type":60,"tag":439,"props":440,"children":441},"style",{},[442],{"type":74,"value":443},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":119,"depth":119,"links":445},[446,447,448,449],{"id":148,"depth":110,"text":151},{"id":215,"depth":110,"text":218},{"id":337,"depth":110,"text":340},{"id":389,"depth":110,"text":392},"markdown","content:http-errors:429-too-many-requests.md","content","http-errors/429-too-many-requests.md","http-errors/429-too-many-requests","md",{"loc":4},1793199802291]