RetryDelays is a lightweight .NET library for generating retry delay strategies.
Simplifies retry logic by removing the need for manual delay calculations - just use the appropriate RetryDelay or RetryDelayOptions.
Supports common retry patterns such as constant, linear, exponential, and time-series delays, including jitter and decorrelated jitter.
Create a retry loop and let RetryDelay calculate delays between attempts.
var delay = ExponentialRetryDelay.Create(
baseDelay: TimeSpan.FromMilliseconds(500),
maxDelay: TimeSpan.FromSeconds(10),
useJitter: true);
int attempt = 0;
while (attempt <= 10)
{
try
{
var result = func();
break;
}
catch (Exception)
{
attempt++;
var nextDelay = delay.GetDelay(attempt);
await Task.Delay(nextDelay, token);
}
}- ⚙️ Supports multiple retry delay strategies - constant, linear, exponential, and time series
- 🎲 Built-in jitter support
- 📈 Decorrelated jitter implementation for exponential backoff, adapted from the Polly
- 🧩 Flexible configuration via
RetryDelayOptions - 🔄 Implicit conversion from
RetryDelayOptionstoRetryDelay - 🧱 Ability to create custom delay strategies using
Func<int, TimeSpan>
RetryDelay: The base class responsible for calculating the exactTimeSpanto wait before the next attempt.RetryDelayOptions: Configuration objects (likeLinearRetryDelayOptionsorConstantRetryDelayOptions) used to define the rules of your delay strategy.- Attempts: Current retry attempt (an integer count starting from 0).
| Type | Description |
|---|---|
| Constant | Same delay for every attempt. |
| Linear | Delay increases linearly: (attempt + 1) * slopeFactor * baseDelay. |
| Exponential | Delay grows exponentially: baseDelay * (exponentialFactor ^ attempt). Decorrelated jitter available. |
| TimeSeries | Uses a predefined sequence of delays. Once exhausted, the last value repeats. |
All types respect the optional MaxDelay limit.
Standard Jitter - Applies ±25% randomization to calculated delays to prevent synchronized retries across distributed systems.
Decorrelated Jitter - Available for exponential delays. Uses an advanced formula that produces smoother, more evenly distributed delays with fewer spikes than standard jitter. Based on techniques from Polly.
Thanks to implicit conversion, you can write methods that accept a RetryDelay but pass configuration options directly:
// Method that accepts a RetryDelay
async Task<T> ExecuteWithRetry<T>(
Func<Task<T>> action,
RetryDelay retryDelay,
CancellationToken cancellationToken = default)
{
int attempt = 0;
while (true)
{
try
{
return await action();
}
catch
{
attempt++;
var delay = retryDelay.GetDelay(attempt);
await Task.Delay(delay, cancellationToken);
}
}
}
// Call the method with an options object - it is implicitly converted to the corresponding RetryDelay
var options = new ExponentialRetryDelayOptions
{
BaseDelay = TimeSpan.FromSeconds(1),
ExponentialFactor = 2.0,
UseJitter = true,
MaxDelay = TimeSpan.FromSeconds(30)
};
var result = await ExecuteWithRetry(() => FetchDataAsync(), options);The options are automatically converted to an ExponentialRetryDelay instance, so the method receives a fully functional delay calculator.
The RetryDelay base class is highly flexible. You can even create a delay strategy directly from a simple function:
Note: The
RetryDelaybase class can be instantiated from aFunc<int, TimeSpan>, allowing for completely custom logic without sub-classing.
// Custom logic: delay is always (attempt * 2) seconds, but never more than 1 minute
RetryDelay customDelay = new RetryDelay(attempt =>
TimeSpan.FromSeconds(Math.Min((attempt + 1) * 2, 60))
);RetryDelays focuses solely on delay calculation, allowing you to integrate it with any retry implementation or resilience framework.
The samples/ directory contains an ASP.NET Core Minimal API that demonstrates library usage with full configuration support.
Key highlights:
IRetryConfiguration— interface that groups four named delay options (DelayOption1–DelayOption4, covering Constant, Exponential, Linear, and TimeSeries strategies)RetryConfiguration— concrete implementation bound from a singleRetryConfigurationsection inappsettings.jsonRetryDelayAnalysisService— service that acceptsIRetryConfigurationand produces a per-attempt delay schedule and total wait time for all four strategiesGET /retry-analysis?attempts=N— endpoint that runs the analysis and returns the full schedule as JSON
See README.md for configuration details and example responses.