releases.shpreview

Step retries support dynamic delay functions

1 featureThis release1 featureNew capabilitiesAI-tallied from the release notes

With Workflows, 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 constant, linear, or exponential.

Step retries now support dynamic delay functions. Instead of choosing only a base delay and backoff strategy, pass a function to retries.delay and calculate the next delay from the failed attempt and thrown error.

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 Retry-After value in its error messaging.

  • JavaScript

    <div><div><span>await</span><span> </span><span>step</span><span>.</span><span>do</span><span>(</span></div></div><div><div><span>  </span><span>"sync customer"</span><span>,</span></div></div><div><div><span>  </span><span>{</span></div></div><div><div><span><span>    </span></span><span>retries</span><span>:</span><span> </span><span>{</span></div></div><div><div><span><span>      </span></span><span>limit</span><span>:</span><span> </span><span>5</span><span>,</span></div></div><div><div><span>      </span><span>delay</span><span>:</span><span> </span><span>({</span><span> </span><span>ctx</span><span>,</span><span> </span><span>error</span><span> </span><span>})</span><span> </span><span>=></span><span> </span><span>{</span></div></div><div><div><span>        </span><span>if</span><span> (</span><span>error</span><span>.</span><span>message</span><span>.</span><span>includes</span><span>(</span><span>"rate limit"</span><span>)) </span><span>{</span></div></div><div><div><span>          </span><span>return</span><span> </span><span>`</span><span>${</span><span>ctx</span><span>.</span><span>attempt</span><span> </span><span>*</span><span> </span><span>30</span><span>}</span><span> seconds`</span><span>;</span></div></div><div><div><span>        </span><span>}</span></div></div><div><div>
    </div></div><div><div><span>        </span><span>return</span><span> </span><span>"10 seconds"</span><span>;</span></div></div><div><div><span>      </span><span>},</span></div></div><div><div><span>    </span><span>},</span></div></div><div><div><span>  </span><span>},</span></div></div><div><div><span>  </span><span>async</span><span> </span><span>()</span><span> </span><span>=></span><span> </span><span>{</span></div></div><div><div><span>    </span><span>await</span><span> </span><span>syncCustomer</span><span>()</span><span>;</span></div></div><div><div><span>  </span><span>},</span></div></div><div><div><span>)</span><span>;</span></div></div>
  • TypeScript

    <div><div><span>await</span><span> </span><span>step</span><span>.</span><span>do</span><span>(</span></div></div><div><div><span>  </span><span>"sync customer"</span><span>,</span></div></div><div><div><span>  </span><span>{</span></div></div><div><div><span><span>    </span></span><span>retries</span><span>:</span><span> </span><span>{</span></div></div><div><div><span><span>      </span></span><span>limit</span><span>:</span><span> </span><span>5</span><span>,</span></div></div><div><div><span>      </span><span>delay</span><span>:</span><span> </span><span>({</span><span> </span><span>ctx</span><span>,</span><span> </span><span>error</span><span> </span><span>})</span><span> </span><span>=></span><span> </span><span>{</span></div></div><div><div><span>        </span><span>if</span><span> (</span><span>error</span><span>.</span><span>message</span><span>.</span><span>includes</span><span>(</span><span>"rate limit"</span><span>)) </span><span>{</span></div></div><div><div><span>          </span><span>return</span><span> </span><span>`</span><span>${</span><span>ctx</span><span>.</span><span>attempt</span><span> </span><span>*</span><span> </span><span>30</span><span>}</span><span> seconds`</span><span>;</span></div></div><div><div><span>        </span><span>}</span></div></div><div><div>
    </div></div><div><div><span>        </span><span>return</span><span> </span><span>"10 seconds"</span><span>;</span></div></div><div><div><span>      </span><span>},</span></div></div><div><div><span>    </span><span>},</span></div></div><div><div><span>  </span><span>},</span></div></div><div><div><span>  </span><span>async</span><span> </span><span>()</span><span> </span><span>=></span><span> </span><span>{</span></div></div><div><div><span>    </span><span>await</span><span> </span><span>syncCustomer</span><span>()</span><span>;</span></div></div><div><div><span>  </span><span>},</span></div></div><div><div><span>)</span><span>;</span></div></div>

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 Sleeping and retrying.

Fetched July 9, 2026

Step retries support dynamic delay functions — Developer… — releases.sh