Fox.RetryKit 1.0.0

dotnet add package Fox.RetryKit --version 1.0.0
                    
NuGet\Install-Package Fox.RetryKit -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Fox.RetryKit" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Fox.RetryKit" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Fox.RetryKit" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Fox.RetryKit --version 1.0.0
                    
#r "nuget: Fox.RetryKit, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Fox.RetryKit@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Fox.RetryKit&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Fox.RetryKit&version=1.0.0
                    
Install as a Cake Tool

Fox.RetryKit

A minimalist, dependency-free retry and timeout utility for C#. Build resilient applications with simple, type-safe retry policies.

Key Features

  • Zero Dependencies - No external dependencies, not even Microsoft.Extensions.*
  • Type-Safe - Fluent API with compile-time safety
  • Flexible - Fixed delays, exponential backoff, custom sequences
  • Timeout Support - Built-in timeout with cancellation token integration
  • Exception Filtering - Retry only specific exception types
  • Async-First - Full support for async/await patterns
  • Observability - OnRetry callbacks, telemetry support
  • Jitter - Random variation to prevent thundering herd
  • Well-Documented - Comprehensive XML documentation

Installation

dotnet add package Fox.RetryKit

Quick Start

Basic Retry

using Fox.RetryKit;

// Retry up to 3 times
var policy = RetryPolicy.Retry(3);

policy.Execute(() =>
{
    CallUnstableService();
});

Retry with Delay

// Retry 3 times with 500ms delay
var policy = RetryPolicy.Retry(3, TimeSpan.FromMilliseconds(500));

await policy.ExecuteAsync(async () =>
{
    await CallUnstableApiAsync();
});

Exponential Backoff

// Retry 5 times with exponential backoff (100ms, 200ms, 400ms, 800ms, 1600ms)
var policy = RetryPolicy.ExponentialBackoff(5, TimeSpan.FromMilliseconds(100));

var result = await policy.ExecuteAsync(async () =>
{
    return await FetchDataAsync();
});

Combined Policy

// Combine retry, delay, timeout, and exception filtering
var policy = RetryPolicy.Retry(3, TimeSpan.FromMilliseconds(500))
    .Handle<HttpRequestException>()
    .WithTimeout(TimeSpan.FromSeconds(10));

var data = await policy.ExecuteAsync(async () =>
{
    return await FetchFromUnstableServiceAsync();
});

Extended Features

OnRetry Callback

var policy = RetryPolicy.Retry(3, TimeSpan.FromMilliseconds(100))
    .OnRetry((exception, attempt, delay) =>
    {
        Console.WriteLine($"Retry {attempt} after {delay.TotalMilliseconds}ms: {exception.Message}");
    });

Jitter (Prevent Thundering Herd)

var policy = RetryPolicy.Retry(5, TimeSpan.FromMilliseconds(200))
    .WithJitter(); // Adds ±25% random variation

MaxDelay Cap

var policy = RetryPolicy.ExponentialBackoff(10, TimeSpan.FromMilliseconds(100))
    .WithMaxDelay(TimeSpan.FromSeconds(5)); // Cap at 5 seconds

WaitAndRetry (Custom Delays)

var delays = new[]
{
    TimeSpan.FromMilliseconds(100),
    TimeSpan.FromMilliseconds(250),
    TimeSpan.FromMilliseconds(500),
    TimeSpan.FromSeconds(1)
};

var policy = RetryPolicy.WaitAndRetry(delays);

Fallback

var policy = RetryPolicy.Retry(3, TimeSpan.FromMilliseconds(100));

// Static fallback value
var result = policy.Fallback(() => GetRemoteData(), "default-value");

// Dynamic fallback provider
var result = policy.Fallback(() => GetPrimaryData(), () => GetCachedData());

RetryIf (Conditional Retry)

var policy = RetryPolicy.Retry(5, TimeSpan.FromMilliseconds(100))
    .RetryIf<HttpResponseMessage>(response => !response.IsSuccessStatusCode);

RetryResult (Telemetry)

var result = await policy.ExecuteWithResultAsync(async () => await FetchDataAsync());

Console.WriteLine($"Success: {result.Success}");
Console.WriteLine($"Attempts: {result.Attempts}");
Console.WriteLine($"Duration: {result.TotalDuration}");

Real-World Examples

HTTP API Calls

var httpPolicy = RetryPolicy.Retry(5, TimeSpan.FromMilliseconds(500))
    .Handle<HttpRequestException>()
    .WithTimeout(TimeSpan.FromSeconds(30));

var response = await httpPolicy.ExecuteAsync(async () =>
{
    using var client = new HttpClient();
    return await client.GetStringAsync("https://api.example.com/data");
});

Database Operations

var dbPolicy = RetryPolicy.ExponentialBackoff(3, TimeSpan.FromSeconds(1))
    .Handle<SqlException>()
    .Handle<TimeoutException>();

await dbPolicy.ExecuteAsync(async () =>
{
    await using var connection = new SqlConnection(connectionString);
    await connection.OpenAsync();
});

File I/O

var filePolicy = RetryPolicy.Retry(3, TimeSpan.FromMilliseconds(100))
    .Handle<IOException>();

var content = filePolicy.Execute(() => File.ReadAllText("config.json"));

API Reference

Static Factories

  • Retry(int count) - Immediate retry
  • Retry(int count, TimeSpan delay) - Fixed delay retry
  • ExponentialBackoff(int retries, TimeSpan initialDelay) - Exponential backoff
  • Timeout(TimeSpan duration) - Timeout constraint
  • WaitAndRetry(IEnumerable<TimeSpan> delays) - Custom delay sequence

Fluent Methods

  • Handle<TException>() - Exception filtering
  • WithTimeout(TimeSpan duration) - Add timeout
  • OnRetry(Action<Exception, int, TimeSpan>) - Retry callback
  • WithJitter() - Add ±25% random variation
  • WithMaxDelay(TimeSpan maxDelay) - Cap maximum delay
  • RetryIf<T>(Func<T, bool> predicate) - Conditional retry

Execution Methods

  • Execute(Action action) - Synchronous execution
  • Execute<T>(Func<T> func) - Synchronous with result
  • ExecuteAsync(Func<Task> func) - Asynchronous execution
  • ExecuteAsync<T>(Func<Task<T>> func) - Asynchronous with result
  • ExecuteWithResult() / ExecuteWithResultAsync() - With telemetry
  • Fallback<T>() / FallbackAsync<T>() - Graceful degradation

License

MIT License - Copyright (c) 2026 Károly Akácz

Contributing

Contributions are welcome! Please open an issue or pull request in the GitHub repository.

Support

If you like Fox.OptionKit, please give it a ⭐ on the GitHub repository!

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 114 2/21/2026

See CHANGELOG.md for release notes.