[{"data":1,"prerenderedAt":1208},["ShallowReactive",2],{"content-query-I1s4VJnwGF":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"layout":10,"crumb":11,"term":11,"summary":12,"group":13,"order":14,"updated":15,"cta":16,"related":24,"faq":43,"body":56,"_type":1201,"_id":1202,"_source":1203,"_file":1204,"_stem":1205,"_extension":1206,"sitemap":1207},"/glossary/exponential-backoff","glossary",false,"","What is exponential backoff? Formula, jitter and examples","Exponential backoff is a retry strategy that doubles the wait after each failed attempt, usually with random jitter and a cap. The formula, code examples and how webhooks use it.","reference","Exponential backoff","Retry with growing waits, usually doubling, plus jitter and a cap.","Delivery and reliability",21,"2026-10-28",{"eyebrow":17,"title":18,"text":19,"to":20,"label":21,"secondaryTo":22,"secondaryLabel":23},"Webhook Relay durable retries","Exponential backoff for every webhook, up to 30 days","Webhook Relay persists each webhook and retries failed deliveries with exponential backoff on a schedule you pick per destination: about 25 minutes, about 16 hours or up to 30 days. You don't have to build the retry loop.","/features/durable-retries/","See durable retries","/docs/webhooks/durable-webhooks/","Configure retry schedules",[25,28,31,34,37,40],{"title":26,"to":27},"Webhook retries","/glossary/webhook-retries/",{"title":29,"to":30},"429 Too Many Requests","/http-errors/429-too-many-requests/",{"title":32,"to":33},"503 Service Unavailable","/http-errors/503-service-unavailable/",{"title":35,"to":36},"Idempotency","/glossary/idempotency/",{"title":38,"to":39},"Dead-letter queue","/glossary/dead-letter-queue/",{"title":41,"to":42},"Throttling","/features/throttling/",[44,47,50,53],{"q":45,"a":46},"What is exponential backoff?","Exponential backoff is a retry strategy in which the wait before each new attempt grows exponentially, usually doubling: 1 second, 2, 4, 8 and so on, up to a maximum delay. It gives a failing service time to recover and stops many clients from retrying in lockstep.",{"q":48,"a":49},"What is the formula for exponential backoff?","The delay before attempt n is base multiplied by 2 to the power of n, capped at a maximum: delay = min(cap, base * 2^n). With jitter, you pick a random value between zero and that delay instead of using it exactly.",{"q":51,"a":52},"What is jitter and why add it?","Jitter is randomness added to each backoff delay. Without it, every client that failed at the same moment retries at the same moment again, creating spikes that can keep the service down. Full jitter, a random delay between zero and the computed backoff, spreads retries out evenly.",{"q":54,"a":55},"When should I not use exponential backoff?","Don't retry errors that will never succeed, such as a 400 for an invalid request or a 401 for a bad API key, without changing something first. If the server sends a Retry-After header, wait at least that long instead of your computed delay.",{"type":57,"children":58,"toc":1193},"root",[59,87,97,104,109,146,151,157,776,782,903,908,914,1076,1082,1102,1120,1131,1137,1187],{"type":60,"tag":61,"props":62,"children":63},"element","p",{},[64,71,73,78,80,85],{"type":60,"tag":65,"props":66,"children":67},"strong",{},[68],{"type":69,"value":70},"text","Exponential backoff is a retry strategy in which the wait before each new attempt grows exponentially, usually doubling: 1 second, then 2, 4, 8, 16, up to a maximum delay.",{"type":69,"value":72}," It gives a struggling service room to recover instead of hammering it while it's down. In practice it's almost always combined with ",{"type":60,"tag":65,"props":74,"children":75},{},[76],{"type":69,"value":77},"jitter",{"type":69,"value":79}," (randomness) and a ",{"type":60,"tag":65,"props":81,"children":82},{},[83],{"type":69,"value":84},"cap",{"type":69,"value":86}," on the delay and the number of attempts.",{"type":60,"tag":88,"props":89,"children":91},"pre",{"code":90},"delay(n) = min(cap, base × 2ⁿ)\nwith full jitter: sleep(random(0, delay(n)))\n\nbase = 1s, cap = 60s\nattempt:  1    2    3    4    5     6     7\ndelay:    1s   2s   4s   8s   16s   32s   60s\n",[92],{"type":60,"tag":93,"props":94,"children":95},"code",{"__ignoreMap":7},[96],{"type":69,"value":90},{"type":60,"tag":98,"props":99,"children":101},"h2",{"id":100},"why-not-just-retry-immediately",[102],{"type":69,"value":103},"Why not just retry immediately?",{"type":60,"tag":61,"props":105,"children":106},{},[107],{"type":69,"value":108},"Immediate or fixed-interval retries cause two problems:",{"type":60,"tag":110,"props":111,"children":112},"ul",{},[113,136],{"type":60,"tag":114,"props":115,"children":116},"li",{},[117,122,124,134],{"type":60,"tag":65,"props":118,"children":119},{},[120],{"type":69,"value":121},"They add load at the worst moment.",{"type":69,"value":123}," A server returning ",{"type":60,"tag":125,"props":126,"children":127},"a",{"href":33},[128],{"type":60,"tag":93,"props":129,"children":131},{"className":130},[],[132],{"type":69,"value":133},"503",{"type":69,"value":135}," because it's overloaded gets more requests from every client retrying.",{"type":60,"tag":114,"props":137,"children":138},{},[139,144],{"type":60,"tag":65,"props":140,"children":141},{},[142],{"type":69,"value":143},"They synchronise clients.",{"type":69,"value":145}," If 10,000 requests fail together and all retry after exactly 5 seconds, the server gets 10,000 requests in the same instant again. This is the \"thundering herd\".",{"type":60,"tag":61,"props":147,"children":148},{},[149],{"type":69,"value":150},"Backoff fixes the first, and jitter fixes the second.",{"type":60,"tag":98,"props":152,"children":154},{"id":153},"example-with-full-jitter",[155],{"type":69,"value":156},"Example with full jitter",{"type":60,"tag":88,"props":158,"children":162},{"code":159,"language":160,"meta":7,"className":161,"style":7},"async function withBackoff(fn, { base = 1000, cap = 60_000, maxAttempts = 7 } = {}) {\n  for (let attempt = 0; ; attempt++) {\n    try {\n      return await fn()\n    } catch (err) {\n      if (attempt + 1 >= maxAttempts || !isRetryable(err)) throw err\n      const retryAfter = err.retryAfterMs            // from a Retry-After header, if any\n      const backoff = Math.min(cap, base * 2 ** attempt)\n      const delay = retryAfter ?? Math.random() * backoff\n      await new Promise((r) => setTimeout(r, delay))\n    }\n  }\n}\n\nconst isRetryable = (err) =>\n  err.code === 'ECONNRESET' || err.code === 'ETIMEDOUT' ||\n  err.status === 429 || err.status >= 500\n","js","language-js shiki shiki-themes github-dark",[163],{"type":60,"tag":93,"props":164,"children":165},{"__ignoreMap":7},[166,273,321,335,359,378,442,471,523,573,622,631,640,649,659,695,739],{"type":60,"tag":167,"props":168,"children":171},"span",{"class":169,"line":170},"line",1,[172,178,183,189,195,201,206,211,216,222,227,231,235,240,244,249,253,258,263,268],{"type":60,"tag":167,"props":173,"children":175},{"style":174},"--shiki-default:#F97583",[176],{"type":69,"value":177},"async",{"type":60,"tag":167,"props":179,"children":180},{"style":174},[181],{"type":69,"value":182}," function",{"type":60,"tag":167,"props":184,"children":186},{"style":185},"--shiki-default:#B392F0",[187],{"type":69,"value":188}," withBackoff",{"type":60,"tag":167,"props":190,"children":192},{"style":191},"--shiki-default:#E1E4E8",[193],{"type":69,"value":194},"(",{"type":60,"tag":167,"props":196,"children":198},{"style":197},"--shiki-default:#FFAB70",[199],{"type":69,"value":200},"fn",{"type":60,"tag":167,"props":202,"children":203},{"style":191},[204],{"type":69,"value":205},", { ",{"type":60,"tag":167,"props":207,"children":208},{"style":197},[209],{"type":69,"value":210},"base",{"type":60,"tag":167,"props":212,"children":213},{"style":174},[214],{"type":69,"value":215}," =",{"type":60,"tag":167,"props":217,"children":219},{"style":218},"--shiki-default:#79B8FF",[220],{"type":69,"value":221}," 1000",{"type":60,"tag":167,"props":223,"children":224},{"style":191},[225],{"type":69,"value":226},", ",{"type":60,"tag":167,"props":228,"children":229},{"style":197},[230],{"type":69,"value":84},{"type":60,"tag":167,"props":232,"children":233},{"style":174},[234],{"type":69,"value":215},{"type":60,"tag":167,"props":236,"children":237},{"style":218},[238],{"type":69,"value":239}," 60_000",{"type":60,"tag":167,"props":241,"children":242},{"style":191},[243],{"type":69,"value":226},{"type":60,"tag":167,"props":245,"children":246},{"style":197},[247],{"type":69,"value":248},"maxAttempts",{"type":60,"tag":167,"props":250,"children":251},{"style":174},[252],{"type":69,"value":215},{"type":60,"tag":167,"props":254,"children":255},{"style":218},[256],{"type":69,"value":257}," 7",{"type":60,"tag":167,"props":259,"children":260},{"style":191},[261],{"type":69,"value":262}," } ",{"type":60,"tag":167,"props":264,"children":265},{"style":174},[266],{"type":69,"value":267},"=",{"type":60,"tag":167,"props":269,"children":270},{"style":191},[271],{"type":69,"value":272}," {}) {\n",{"type":60,"tag":167,"props":274,"children":276},{"class":169,"line":275},2,[277,282,287,292,297,301,306,311,316],{"type":60,"tag":167,"props":278,"children":279},{"style":174},[280],{"type":69,"value":281},"  for",{"type":60,"tag":167,"props":283,"children":284},{"style":191},[285],{"type":69,"value":286}," (",{"type":60,"tag":167,"props":288,"children":289},{"style":174},[290],{"type":69,"value":291},"let",{"type":60,"tag":167,"props":293,"children":294},{"style":191},[295],{"type":69,"value":296}," attempt ",{"type":60,"tag":167,"props":298,"children":299},{"style":174},[300],{"type":69,"value":267},{"type":60,"tag":167,"props":302,"children":303},{"style":218},[304],{"type":69,"value":305}," 0",{"type":60,"tag":167,"props":307,"children":308},{"style":191},[309],{"type":69,"value":310},"; ; attempt",{"type":60,"tag":167,"props":312,"children":313},{"style":174},[314],{"type":69,"value":315},"++",{"type":60,"tag":167,"props":317,"children":318},{"style":191},[319],{"type":69,"value":320},") {\n",{"type":60,"tag":167,"props":322,"children":324},{"class":169,"line":323},3,[325,330],{"type":60,"tag":167,"props":326,"children":327},{"style":174},[328],{"type":69,"value":329},"    try",{"type":60,"tag":167,"props":331,"children":332},{"style":191},[333],{"type":69,"value":334}," {\n",{"type":60,"tag":167,"props":336,"children":338},{"class":169,"line":337},4,[339,344,349,354],{"type":60,"tag":167,"props":340,"children":341},{"style":174},[342],{"type":69,"value":343},"      return",{"type":60,"tag":167,"props":345,"children":346},{"style":174},[347],{"type":69,"value":348}," await",{"type":60,"tag":167,"props":350,"children":351},{"style":185},[352],{"type":69,"value":353}," fn",{"type":60,"tag":167,"props":355,"children":356},{"style":191},[357],{"type":69,"value":358},"()\n",{"type":60,"tag":167,"props":360,"children":362},{"class":169,"line":361},5,[363,368,373],{"type":60,"tag":167,"props":364,"children":365},{"style":191},[366],{"type":69,"value":367},"    } ",{"type":60,"tag":167,"props":369,"children":370},{"style":174},[371],{"type":69,"value":372},"catch",{"type":60,"tag":167,"props":374,"children":375},{"style":191},[376],{"type":69,"value":377}," (err) {\n",{"type":60,"tag":167,"props":379,"children":381},{"class":169,"line":380},6,[382,387,392,397,402,407,412,417,422,427,432,437],{"type":60,"tag":167,"props":383,"children":384},{"style":174},[385],{"type":69,"value":386},"      if",{"type":60,"tag":167,"props":388,"children":389},{"style":191},[390],{"type":69,"value":391}," (attempt ",{"type":60,"tag":167,"props":393,"children":394},{"style":174},[395],{"type":69,"value":396},"+",{"type":60,"tag":167,"props":398,"children":399},{"style":218},[400],{"type":69,"value":401}," 1",{"type":60,"tag":167,"props":403,"children":404},{"style":174},[405],{"type":69,"value":406}," >=",{"type":60,"tag":167,"props":408,"children":409},{"style":191},[410],{"type":69,"value":411}," maxAttempts ",{"type":60,"tag":167,"props":413,"children":414},{"style":174},[415],{"type":69,"value":416},"||",{"type":60,"tag":167,"props":418,"children":419},{"style":174},[420],{"type":69,"value":421}," !",{"type":60,"tag":167,"props":423,"children":424},{"style":185},[425],{"type":69,"value":426},"isRetryable",{"type":60,"tag":167,"props":428,"children":429},{"style":191},[430],{"type":69,"value":431},"(err)) ",{"type":60,"tag":167,"props":433,"children":434},{"style":174},[435],{"type":69,"value":436},"throw",{"type":60,"tag":167,"props":438,"children":439},{"style":191},[440],{"type":69,"value":441}," err\n",{"type":60,"tag":167,"props":443,"children":445},{"class":169,"line":444},7,[446,451,456,460,465],{"type":60,"tag":167,"props":447,"children":448},{"style":174},[449],{"type":69,"value":450},"      const",{"type":60,"tag":167,"props":452,"children":453},{"style":218},[454],{"type":69,"value":455}," retryAfter",{"type":60,"tag":167,"props":457,"children":458},{"style":174},[459],{"type":69,"value":215},{"type":60,"tag":167,"props":461,"children":462},{"style":191},[463],{"type":69,"value":464}," err.retryAfterMs            ",{"type":60,"tag":167,"props":466,"children":468},{"style":467},"--shiki-default:#6A737D",[469],{"type":69,"value":470},"// from a Retry-After header, if any\n",{"type":60,"tag":167,"props":472,"children":474},{"class":169,"line":473},8,[475,479,484,488,493,498,503,508,513,518],{"type":60,"tag":167,"props":476,"children":477},{"style":174},[478],{"type":69,"value":450},{"type":60,"tag":167,"props":480,"children":481},{"style":218},[482],{"type":69,"value":483}," backoff",{"type":60,"tag":167,"props":485,"children":486},{"style":174},[487],{"type":69,"value":215},{"type":60,"tag":167,"props":489,"children":490},{"style":191},[491],{"type":69,"value":492}," Math.",{"type":60,"tag":167,"props":494,"children":495},{"style":185},[496],{"type":69,"value":497},"min",{"type":60,"tag":167,"props":499,"children":500},{"style":191},[501],{"type":69,"value":502},"(cap, base ",{"type":60,"tag":167,"props":504,"children":505},{"style":174},[506],{"type":69,"value":507},"*",{"type":60,"tag":167,"props":509,"children":510},{"style":218},[511],{"type":69,"value":512}," 2",{"type":60,"tag":167,"props":514,"children":515},{"style":174},[516],{"type":69,"value":517}," **",{"type":60,"tag":167,"props":519,"children":520},{"style":191},[521],{"type":69,"value":522}," attempt)\n",{"type":60,"tag":167,"props":524,"children":526},{"class":169,"line":525},9,[527,531,536,540,545,550,554,559,564,568],{"type":60,"tag":167,"props":528,"children":529},{"style":174},[530],{"type":69,"value":450},{"type":60,"tag":167,"props":532,"children":533},{"style":218},[534],{"type":69,"value":535}," delay",{"type":60,"tag":167,"props":537,"children":538},{"style":174},[539],{"type":69,"value":215},{"type":60,"tag":167,"props":541,"children":542},{"style":191},[543],{"type":69,"value":544}," retryAfter ",{"type":60,"tag":167,"props":546,"children":547},{"style":174},[548],{"type":69,"value":549},"??",{"type":60,"tag":167,"props":551,"children":552},{"style":191},[553],{"type":69,"value":492},{"type":60,"tag":167,"props":555,"children":556},{"style":185},[557],{"type":69,"value":558},"random",{"type":60,"tag":167,"props":560,"children":561},{"style":191},[562],{"type":69,"value":563},"() ",{"type":60,"tag":167,"props":565,"children":566},{"style":174},[567],{"type":69,"value":507},{"type":60,"tag":167,"props":569,"children":570},{"style":191},[571],{"type":69,"value":572}," backoff\n",{"type":60,"tag":167,"props":574,"children":576},{"class":169,"line":575},10,[577,582,587,592,597,602,607,612,617],{"type":60,"tag":167,"props":578,"children":579},{"style":174},[580],{"type":69,"value":581},"      await",{"type":60,"tag":167,"props":583,"children":584},{"style":174},[585],{"type":69,"value":586}," new",{"type":60,"tag":167,"props":588,"children":589},{"style":218},[590],{"type":69,"value":591}," Promise",{"type":60,"tag":167,"props":593,"children":594},{"style":191},[595],{"type":69,"value":596},"((",{"type":60,"tag":167,"props":598,"children":599},{"style":197},[600],{"type":69,"value":601},"r",{"type":60,"tag":167,"props":603,"children":604},{"style":191},[605],{"type":69,"value":606},") ",{"type":60,"tag":167,"props":608,"children":609},{"style":174},[610],{"type":69,"value":611},"=>",{"type":60,"tag":167,"props":613,"children":614},{"style":185},[615],{"type":69,"value":616}," setTimeout",{"type":60,"tag":167,"props":618,"children":619},{"style":191},[620],{"type":69,"value":621},"(r, delay))\n",{"type":60,"tag":167,"props":623,"children":625},{"class":169,"line":624},11,[626],{"type":60,"tag":167,"props":627,"children":628},{"style":191},[629],{"type":69,"value":630},"    }\n",{"type":60,"tag":167,"props":632,"children":634},{"class":169,"line":633},12,[635],{"type":60,"tag":167,"props":636,"children":637},{"style":191},[638],{"type":69,"value":639},"  }\n",{"type":60,"tag":167,"props":641,"children":643},{"class":169,"line":642},13,[644],{"type":60,"tag":167,"props":645,"children":646},{"style":191},[647],{"type":69,"value":648},"}\n",{"type":60,"tag":167,"props":650,"children":652},{"class":169,"line":651},14,[653],{"type":60,"tag":167,"props":654,"children":656},{"emptyLinePlaceholder":655},true,[657],{"type":69,"value":658},"\n",{"type":60,"tag":167,"props":660,"children":662},{"class":169,"line":661},15,[663,668,673,677,681,686,690],{"type":60,"tag":167,"props":664,"children":665},{"style":174},[666],{"type":69,"value":667},"const",{"type":60,"tag":167,"props":669,"children":670},{"style":185},[671],{"type":69,"value":672}," isRetryable",{"type":60,"tag":167,"props":674,"children":675},{"style":174},[676],{"type":69,"value":215},{"type":60,"tag":167,"props":678,"children":679},{"style":191},[680],{"type":69,"value":286},{"type":60,"tag":167,"props":682,"children":683},{"style":197},[684],{"type":69,"value":685},"err",{"type":60,"tag":167,"props":687,"children":688},{"style":191},[689],{"type":69,"value":606},{"type":60,"tag":167,"props":691,"children":692},{"style":174},[693],{"type":69,"value":694},"=>\n",{"type":60,"tag":167,"props":696,"children":698},{"class":169,"line":697},16,[699,704,709,715,720,725,729,734],{"type":60,"tag":167,"props":700,"children":701},{"style":191},[702],{"type":69,"value":703},"  err.code ",{"type":60,"tag":167,"props":705,"children":706},{"style":174},[707],{"type":69,"value":708},"===",{"type":60,"tag":167,"props":710,"children":712},{"style":711},"--shiki-default:#9ECBFF",[713],{"type":69,"value":714}," 'ECONNRESET'",{"type":60,"tag":167,"props":716,"children":717},{"style":174},[718],{"type":69,"value":719}," ||",{"type":60,"tag":167,"props":721,"children":722},{"style":191},[723],{"type":69,"value":724}," err.code ",{"type":60,"tag":167,"props":726,"children":727},{"style":174},[728],{"type":69,"value":708},{"type":60,"tag":167,"props":730,"children":731},{"style":711},[732],{"type":69,"value":733}," 'ETIMEDOUT'",{"type":60,"tag":167,"props":735,"children":736},{"style":174},[737],{"type":69,"value":738}," ||\n",{"type":60,"tag":167,"props":740,"children":742},{"class":169,"line":741},17,[743,748,752,757,761,766,771],{"type":60,"tag":167,"props":744,"children":745},{"style":191},[746],{"type":69,"value":747},"  err.status ",{"type":60,"tag":167,"props":749,"children":750},{"style":174},[751],{"type":69,"value":708},{"type":60,"tag":167,"props":753,"children":754},{"style":218},[755],{"type":69,"value":756}," 429",{"type":60,"tag":167,"props":758,"children":759},{"style":174},[760],{"type":69,"value":719},{"type":60,"tag":167,"props":762,"children":763},{"style":191},[764],{"type":69,"value":765}," err.status ",{"type":60,"tag":167,"props":767,"children":768},{"style":174},[769],{"type":69,"value":770},">=",{"type":60,"tag":167,"props":772,"children":773},{"style":218},[774],{"type":69,"value":775}," 500\n",{"type":60,"tag":98,"props":777,"children":779},{"id":778},"jitter-strategies",[780],{"type":69,"value":781},"Jitter strategies",{"type":60,"tag":783,"props":784,"children":785},"table",{},[786,810],{"type":60,"tag":787,"props":788,"children":789},"thead",{},[790],{"type":60,"tag":791,"props":792,"children":793},"tr",{},[794,800,805],{"type":60,"tag":795,"props":796,"children":797},"th",{},[798],{"type":69,"value":799},"Strategy",{"type":60,"tag":795,"props":801,"children":802},{},[803],{"type":69,"value":804},"Delay",{"type":60,"tag":795,"props":806,"children":807},{},[808],{"type":69,"value":809},"Notes",{"type":60,"tag":811,"props":812,"children":813},"tbody",{},[814,837,859,881],{"type":60,"tag":791,"props":815,"children":816},{},[817,823,832],{"type":60,"tag":818,"props":819,"children":820},"td",{},[821],{"type":69,"value":822},"No jitter",{"type":60,"tag":818,"props":824,"children":825},{},[826],{"type":60,"tag":93,"props":827,"children":829},{"className":828},[],[830],{"type":69,"value":831},"base × 2ⁿ",{"type":60,"tag":818,"props":833,"children":834},{},[835],{"type":69,"value":836},"Clients stay synchronised",{"type":60,"tag":791,"props":838,"children":839},{},[840,845,854],{"type":60,"tag":818,"props":841,"children":842},{},[843],{"type":69,"value":844},"Full jitter",{"type":60,"tag":818,"props":846,"children":847},{},[848],{"type":60,"tag":93,"props":849,"children":851},{"className":850},[],[852],{"type":69,"value":853},"random(0, base × 2ⁿ)",{"type":60,"tag":818,"props":855,"children":856},{},[857],{"type":69,"value":858},"Spreads load best, a good default",{"type":60,"tag":791,"props":860,"children":861},{},[862,867,876],{"type":60,"tag":818,"props":863,"children":864},{},[865],{"type":69,"value":866},"Equal jitter",{"type":60,"tag":818,"props":868,"children":869},{},[870],{"type":60,"tag":93,"props":871,"children":873},{"className":872},[],[874],{"type":69,"value":875},"d/2 + random(0, d/2)",{"type":60,"tag":818,"props":877,"children":878},{},[879],{"type":69,"value":880},"Guarantees a minimum wait",{"type":60,"tag":791,"props":882,"children":883},{},[884,889,898],{"type":60,"tag":818,"props":885,"children":886},{},[887],{"type":69,"value":888},"Decorrelated jitter",{"type":60,"tag":818,"props":890,"children":891},{},[892],{"type":60,"tag":93,"props":893,"children":895},{"className":894},[],[896],{"type":69,"value":897},"random(base, prev × 3)",{"type":60,"tag":818,"props":899,"children":900},{},[901],{"type":69,"value":902},"Grows from the previous delay",{"type":60,"tag":61,"props":904,"children":905},{},[906],{"type":69,"value":907},"AWS's architecture blog analysed these and found full and decorrelated jitter do the least total work.",{"type":60,"tag":98,"props":909,"children":911},{"id":910},"what-to-retry-and-what-not-to",[912],{"type":69,"value":913},"What to retry, and what not to",{"type":60,"tag":110,"props":915,"children":916},{},[917,980,1026,1043],{"type":60,"tag":114,"props":918,"children":919},{},[920,925,927,936,937,947,948,958,959,967,968,978],{"type":60,"tag":65,"props":921,"children":922},{},[923],{"type":69,"value":924},"Retry:",{"type":69,"value":926}," timeouts, connection resets, DNS failures, ",{"type":60,"tag":125,"props":928,"children":929},{"href":30},[930],{"type":60,"tag":93,"props":931,"children":933},{"className":932},[],[934],{"type":69,"value":935},"429",{"type":69,"value":226},{"type":60,"tag":125,"props":938,"children":940},{"href":939},"/http-errors/500-internal-server-error/",[941],{"type":60,"tag":93,"props":942,"children":944},{"className":943},[],[945],{"type":69,"value":946},"500",{"type":69,"value":226},{"type":60,"tag":125,"props":949,"children":951},{"href":950},"/http-errors/502-bad-gateway/",[952],{"type":60,"tag":93,"props":953,"children":955},{"className":954},[],[956],{"type":69,"value":957},"502",{"type":69,"value":226},{"type":60,"tag":125,"props":960,"children":961},{"href":33},[962],{"type":60,"tag":93,"props":963,"children":965},{"className":964},[],[966],{"type":69,"value":133},{"type":69,"value":226},{"type":60,"tag":125,"props":969,"children":971},{"href":970},"/http-errors/504-gateway-timeout/",[972],{"type":60,"tag":93,"props":973,"children":975},{"className":974},[],[976],{"type":69,"value":977},"504",{"type":69,"value":979},".",{"type":60,"tag":114,"props":981,"children":982},{},[983,988,990,996,997,1003,1004,1010,1011,1017,1018,1024],{"type":60,"tag":65,"props":984,"children":985},{},[986],{"type":69,"value":987},"Don't retry blindly:",{"type":69,"value":989}," ",{"type":60,"tag":93,"props":991,"children":993},{"className":992},[],[994],{"type":69,"value":995},"400",{"type":69,"value":226},{"type":60,"tag":93,"props":998,"children":1000},{"className":999},[],[1001],{"type":69,"value":1002},"401",{"type":69,"value":226},{"type":60,"tag":93,"props":1005,"children":1007},{"className":1006},[],[1008],{"type":69,"value":1009},"403",{"type":69,"value":226},{"type":60,"tag":93,"props":1012,"children":1014},{"className":1013},[],[1015],{"type":69,"value":1016},"404",{"type":69,"value":226},{"type":60,"tag":93,"props":1019,"children":1021},{"className":1020},[],[1022],{"type":69,"value":1023},"422",{"type":69,"value":1025},". They'll fail the same way until something changes.",{"type":60,"tag":114,"props":1027,"children":1028},{},[1029,1041],{"type":60,"tag":65,"props":1030,"children":1031},{},[1032,1034,1040],{"type":69,"value":1033},"Honour ",{"type":60,"tag":93,"props":1035,"children":1037},{"className":1036},[],[1038],{"type":69,"value":1039},"Retry-After",{"type":69,"value":979},{"type":69,"value":1042}," If the server says when to come back, wait at least that long.",{"type":60,"tag":114,"props":1044,"children":1045},{},[1046,1051,1053,1059,1061,1066,1068,1074],{"type":60,"tag":65,"props":1047,"children":1048},{},[1049],{"type":69,"value":1050},"Make retries safe.",{"type":69,"value":1052}," Retrying a ",{"type":60,"tag":93,"props":1054,"children":1056},{"className":1055},[],[1057],{"type":69,"value":1058},"POST",{"type":69,"value":1060}," that half-succeeded can create duplicates unless the operation is ",{"type":60,"tag":125,"props":1062,"children":1063},{"href":36},[1064],{"type":69,"value":1065},"idempotent",{"type":69,"value":1067},", for example by sending an ",{"type":60,"tag":93,"props":1069,"children":1071},{"className":1070},[],[1072],{"type":69,"value":1073},"Idempotency-Key",{"type":69,"value":1075}," header.",{"type":60,"tag":98,"props":1077,"children":1079},{"id":1078},"exponential-backoff-in-webhooks",[1080],{"type":69,"value":1081},"Exponential backoff in webhooks",{"type":60,"tag":61,"props":1083,"children":1084},{},[1085,1087,1092,1094,1100],{"type":69,"value":1086},"Webhook providers use backoff for ",{"type":60,"tag":125,"props":1088,"children":1089},{"href":27},[1090],{"type":69,"value":1091},"webhook retries",{"type":69,"value":1093},": early retries come quickly to cover blips, later ones are hours apart to cover outages. Real schedules are often hand-tuned rather than pure doubling. The Webhook Relay ",{"type":60,"tag":125,"props":1095,"children":1097},{"href":1096},"/outbound-webhooks/",[1098],{"type":69,"value":1099},"Outbound Gateway",{"type":69,"value":1101},", for instance, retries after 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours, 10 hours and 10 hours, up to 8 attempts within 48 hours.",{"type":60,"tag":61,"props":1103,"children":1104},{},[1105,1107,1112,1114,1119],{"type":69,"value":1106},"For inbound webhooks, Webhook Relay's ",{"type":60,"tag":125,"props":1108,"children":1109},{"href":20},[1110],{"type":69,"value":1111},"durable retries",{"type":69,"value":1113}," run fast retries for a handoff window (15 minutes by default), then retry with exponential backoff on the schedule you choose: Seconds (about 25 minutes total), Medium (about 16 hours) or Long (up to 30 days). Details are in the ",{"type":60,"tag":125,"props":1115,"children":1116},{"href":22},[1117],{"type":69,"value":1118},"durable webhooks docs",{"type":69,"value":979},{"type":60,"tag":61,"props":1121,"children":1122},{},[1123,1125,1129],{"type":69,"value":1124},"If the problem is a burst rather than an outage, backoff alone isn't enough. ",{"type":60,"tag":125,"props":1126,"children":1127},{"href":42},[1128],{"type":69,"value":41},{"type":69,"value":1130}," releases queued webhooks to your endpoint at a steady rate or concurrency, so it never sees the spike.",{"type":60,"tag":98,"props":1132,"children":1134},{"id":1133},"common-mistakes",[1135],{"type":69,"value":1136},"Common mistakes",{"type":60,"tag":110,"props":1138,"children":1139},{},[1140,1150,1167,1177],{"type":60,"tag":114,"props":1141,"children":1142},{},[1143,1148],{"type":60,"tag":65,"props":1144,"children":1145},{},[1146],{"type":69,"value":1147},"No cap.",{"type":69,"value":1149}," Without a maximum, the 20th retry waits 12 days.",{"type":60,"tag":114,"props":1151,"children":1152},{},[1153,1158,1160,1165],{"type":60,"tag":65,"props":1154,"children":1155},{},[1156],{"type":69,"value":1157},"No attempt limit or deadline.",{"type":69,"value":1159}," Eventually give up and move the work to a ",{"type":60,"tag":125,"props":1161,"children":1162},{"href":39},[1163],{"type":69,"value":1164},"dead-letter queue",{"type":69,"value":1166}," for inspection.",{"type":60,"tag":114,"props":1168,"children":1169},{},[1170,1175],{"type":60,"tag":65,"props":1171,"children":1172},{},[1173],{"type":69,"value":1174},"Retrying at several layers.",{"type":69,"value":1176}," If the HTTP client, the SDK and your job queue all retry with backoff, one failure can become dozens of attempts.",{"type":60,"tag":114,"props":1178,"children":1179},{},[1180,1185],{"type":60,"tag":65,"props":1181,"children":1182},{},[1183],{"type":69,"value":1184},"Backing off in the request path.",{"type":69,"value":1186}," Sleeping inside a web request ties up a worker. Schedule the retry in a queue instead.",{"type":60,"tag":1188,"props":1189,"children":1190},"style",{},[1191],{"type":69,"value":1192},"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":323,"depth":323,"links":1194},[1195,1196,1197,1198,1199,1200],{"id":100,"depth":275,"text":103},{"id":153,"depth":275,"text":156},{"id":778,"depth":275,"text":781},{"id":910,"depth":275,"text":913},{"id":1078,"depth":275,"text":1081},{"id":1133,"depth":275,"text":1136},"markdown","content:glossary:exponential-backoff.md","content","glossary/exponential-backoff.md","glossary/exponential-backoff","md",{"loc":4},1793199805417]