Sign inConnect your agent
infochanged

Workflows - Workflows now supports delay functions when retrying

Announced
Tags
Workflows
Severity
info, set by reef/rss-rule-v1
Source
https://developers.cloudflare.com/changelog/post/2026-07-09-dynamic-retry-delays/

<p>With <a href="https://developers.cloudflare.com/workflows/">Workflows</a>, you can configure built-in retry behavior for each step. Previously, you could configure step retries with fixed delay durations, such as seconds, minutes, or hours, and backoff strategies such as <code>constant</code>, <code>linear</code>, or <code>exponential</code>.</p> <p>Step retries now support dynamic delay functions. Instead of choosing only a base delay and backoff strategy, pass a function to <code>retries.delay</code> and calculate the next delay from the failed attempt and thrown error.</p> <p>This is useful when retries should depend on the failure. Your Workflow may need to wait longer after a rate-limit error, but retry sooner after a short network failure. The delay function can also accommodate provider guidance if, for example, a downstream API returns a <code>Retry-After</code> value in its error messaging.</p> <div><div data-nb-tabs data-nb-sync-key="workersExamples" class><div class="relative flex border-b border-border" role="tablist" data-nb-tabs-list><span class="bg-primary pointer-events-none absolute -bottom-px h-0.5 rounded-t-sm transition-[left,width] duration-200 ease-out" data-nb-tabs-indicator aria-hidden="true"></span></div><div class="mt-3"><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="JavaScript" class><figure class="nb-code-figure" data-nb-lang="js"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="js" data-nb-lang="js"><code><span class="line"><span class="nb-shiki-1itgoe">await</span><span class="nb-shiki-140thh"> step.</span><span class="nb-shiki-1t8gfj">do</span><span class="nb-shiki-140thh">(</span></span> <span class="line"><span class="nb-shiki-mdbnqw"> "sync customer"</span><span class="nb-shiki-140thh">,</span></span> <span class="line"><span class="nb-shiki-140thh"> {</span></span> <span class="line"><span class="nb-shiki-140thh"> retries: {</span></span> <span class="line"><span class="nb-shiki-140thh"> limit: </span><span class="nb-shiki-dzsirb">5</span><span class="nb-shiki-140thh">,</span></span> <span class="line"><span class="nb-shiki-1t8gfj"> delay</span><span class="nb-shiki-140thh">: ({ </span><span class="nb-shiki-1jdh33">ctx</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-1jdh33">error</span><span class="nb-shiki-140thh"> }) </span><span class="nb-shiki-1itgoe">=></span><span class="nb-shiki-140thh"> {</span></span> <span class="line"><span class="nb-shiki-1itgoe"> if</span><span class="nb-shiki-140thh"> (error.message.</span><span class="nb-shiki-1t8gfj">includes</span><span class="nb-shiki-140thh">(</span><span class="nb-shiki-mdbnqw">"rate limit"</span><span class="nb-shiki-140thh">)) {</span></span> <span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-mdbnqw"> ${</span><span class="nb-shiki-140thh">ctx</span><span class="nb-shiki-mdbnqw">.</span><span class="nb-shiki-140thh">attempt</span><span class="nb-shiki-1itgoe"> *</span><span class="nb-shiki-dzsirb"> 30</span><span class="nb-shiki-mdbnqw">} seconds</span><span class="nb-shiki-140thh">;</span></span> <span class="line"><span class="nb-shiki-140thh"> }</span></span> <span class="line"></span> <span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-mdbnqw"> "10 seconds"</span><span class="nb-shiki-140thh">;</span></span> <span class="line"><span class="nb-shiki-140thh"> },</span></span> <span class="line"><span class="nb-shiki-140thh"> },</span></span> <span class="line"><span class="nb-shiki-140thh"> },</span></span> <span class="line"><span class="nb-shiki-1itgoe"> async</span><span class="nb-shiki-140thh"> () </span><span class="nb-shiki-1itgoe">=></span><span class="nb-shiki-140thh"> {</span></span> <span class="line"><span class="nb-shiki-1itgoe"> await</span><span class="nb-shiki-1t8gfj"> syncCustomer</span><span class="nb-shiki-140thh">();</span></span> <span class="line"><span class="nb-shiki-140thh"> },</span></span> <span class="line"><span class="nb-shiki-140thh">);</span></span></code></pre></figure></div><div role="tabpanel" data-nb-tabs-content data-nb-tab-label="TypeScript" class><figure class="nb-code-figure" data-nb-lang="ts"><pre class="astro-code astro-code-themes github-light github-dark nb-shiki-c6xiwz" tabindex="0" data-language="ts" data-nb-lang="ts"><code><span class="line"><span class="nb-shiki-1itgoe">await</span><span class="nb-shiki-140thh"> step.</span><span class="nb-shiki-1t8gfj">do</span><span class="nb-shiki-140thh">(</span></span> <span class="line"><span class="nb-shiki-mdbnqw"> "sync customer"</span><span class="nb-shiki-140thh">,</span></span> <span class="line"><span class="nb-shiki-140thh"> {</span></span> <span class="line"><span class="nb-shiki-140thh"> retries: {</span></span> <span class="line"><span class="nb-shiki-140thh"> limit: </span><span class="nb-shiki-dzsirb">5</span><span class="nb-shiki-140thh">,</span></span> <span class="line"><span class="nb-shiki-1t8gfj"> delay</span><span class="nb-shiki-140thh">: ({ </span><span class="nb-shiki-1jdh33">ctx</span><span class="nb-shiki-140thh">, </span><span class="nb-shiki-1jdh33">error</span><span class="nb-shiki-140thh"> }) </span><span class="nb-shiki-1itgoe">=&gt;</span><span class="nb-shiki-140thh"> {</span></span> <span class="line"><span class="nb-shiki-1itgoe"> if</span><span class="nb-shiki-140thh"> (error.message.</span><span class="nb-shiki-1t8gfj">includes</span><span class="nb-shiki-140thh">(</span><span class="nb-shiki-mdbnqw">"rate limit"</span><span class="nb-shiki-140thh">)) {</span></span> <span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-mdbnqw"> ${</span><span class="nb-shiki-140thh">ctx</span><span class="nb-shiki-mdbnqw">.</span><span class="nb-shiki-140thh">attempt</span><span class="nb-shiki-1itgoe"> *</span><span class="nb-shiki-dzsirb"> 30</span><span class="nb-shiki-mdbnqw">} seconds</span><span class="nb-shiki-140thh">;</span></span> <span class="line"><span class="nb-shiki-140thh"> }</span></span> <span class="line"></span> <span class="line"><span class="nb-shiki-1itgoe"> return</span><span class="nb-shiki-mdbnqw"> "10 seconds"</span><span class="nb-shiki-140thh">;</span></span> <span class="line"><span class="nb-shiki-140thh"> },</span></span> <span class="line"><span class="nb-shiki-140thh"> },</span></span> <span class="line"><span class="nb-shiki-140thh"> },</span></span> <span class="line"><span class="nb-shiki-1itgoe"> async</span><span class="nb-shiki-140thh"> () </span><span class="nb-shiki-1itgoe">=&gt;</span><span class="nb-shiki-140thh"> {</span></span> <span class="line"><span class="nb-shiki-1itgoe"> await</span><span class="nb-shiki-1t8gfj"> syncCustomer</span><span class="nb-shiki-140thh">();</span></span> <span class="line"><span class="nb-shiki-140thh"> },</span></span> <span class="line"><span class="nb-shiki-140thh">);</span></span></code></pre></figure></div></div></div><script type="module" src="https://developers.cloudflare.com/home/runner/work/cloudflare-docs/cloudflare-docs/src/components/ui/tabs/Tabs.astro?astro&type=script&index=0&lang.ts"></script></div> <p>Dynamic delay functions can return a duration string, a number, or a promise that resolves to a duration. Use them to add adaptive retry behavior without writing separate queue or scheduling logic. For more information, refer to <a href="https://developers.cloudflare.com/workflows/build/sleeping-and-retrying/">Sleeping and retrying</a>.</p>

The text above is the source's. reef added the severity, the dates it could read from the text, and the endpoints and scopes named in code.