Carom 2.0.0

dotnet add package Carom --version 2.0.0
                    
NuGet\Install-Package Carom -Version 2.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="Carom" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Carom" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Carom" />
                    
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 Carom --version 2.0.0
                    
#r "nuget: Carom, 2.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 Carom@2.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=Carom&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Carom&version=2.0.0
                    
Install as a Cake Tool

Carom 🎱

A lean, fast, and safe resilience library for .NET

NuGet License .NET

Carom is a zero-dependency resilience library that enforces best practices by default. Named after the billiards shot where the ball bounces before reaching its target, Carom helps your code gracefully handle failures.

Runs on .NET 10 and .NET 8. The core packages target netstandard2.0, so .NET Framework and older .NET are supported too; the ASP.NET Core, EF Core and OpenTelemetry packages target net8.0;net10.0. Tests run on both runtimes in CI.

🎯 Why Carom?

  • Zero Dependencies (core packages)
  • Zero Allocations (0 bytes on the successful hot path, test-enforced)
  • Safe by Default (mandatory decorrelated jitter)
  • Tiny Footprint (21.5KB core, 53.5KB extensions)
  • Fully Composable (all patterns work together)

📦 Packages

Sizes are the Release-built assemblies. Tests keep the core and extensions figures honest.

Package Size Purpose
Carom 21.5KB Core retry + timeout
Carom.Extensions 53.5KB Circuit Breaker, Fallback, Bulkhead, Rate Limiting
Carom.Http 13KB HTTP integration
Carom.AspNetCore 9KB ASP.NET Core health checks
Carom.EntityFramework 10KB EF Core retry
Carom.Telemetry.OpenTelemetry 7KB OpenTelemetry instruments, called by your code (Carom does not emit automatically yet)

🚀 Quick Start

Installation

dotnet add package Carom
dotnet add package Carom.Extensions

Basic Usage

using Carom;

// Simple retry with exponential backoff
var result = await Carom.ShotAsync(() => api.CallAsync(), retries: 3);

// With timeout
var bounce = Bounce.Times(5).WithTimeout(TimeSpan.FromSeconds(30));
var data = await Carom.ShotAsync(() => apiClient.FetchAsync(), bounce);

Circuit Breaker

using Carom.Extensions;

var cushion = Cushion.ForService("payment-api")
    .OpenAfter(failures: 5, trackingLast: 10)
    .WithinLast(TimeSpan.FromMinutes(1))
    .When(ex => ex is HttpRequestException)
    .HalfOpenAfter(TimeSpan.FromSeconds(30));

var payment = await CaromCushionExtensions.ShotAsync(
    () => paymentApi.Charge(), 
    cushion);

The circuit opens as soon as 5 failures are recorded. trackingLast bounds how far back failures are counted, and WithinLast expires them by age, so an old incident cannot combine with a fresh failure to trip the breaker. When decides which exceptions count as the dependency's fault: without it, a bug in your own calling code would open the circuit on a healthy service. Retries run inside the breaker, so one logical call records one outcome no matter how many attempts it took.

Fallback

var config = await new Func<Task<AppConfig>>(() => configService.LoadAsync())
    .PocketAsync(AppConfig.Default);

Bulkhead

var dbCompartment = Compartment.ForResource("database")
    .WithMaxConcurrency(10)
    .Build();

var query = await CaromCompartmentExtensions.ShotAsync(
    () => db.QueryAsync(sql), 
    dbCompartment);

Rate Limiting

var apiThrottle = Throttle.ForService("external-api")
    .WithRate(100, TimeSpan.FromSeconds(1))
    .WithBurst(20)
    .Build();

var apiResult = await CaromThrottleExtensions.ShotAsync(
    () => apiClient.CallAsync(), 
    apiThrottle);

🎓 Patterns

Pattern Class Purpose
Retry Carom Exponential backoff with jitter
Timeout Bounce.WithTimeout() Operation timeout
Circuit Breaker Cushion Prevent cascade failures
Fallback Pocket/PocketAsync Graceful degradation
Bulkhead Compartment Concurrency control
Rate Limiting Throttle Token bucket algorithm

�� Documentation

🤝 Contributing

Contributions welcome! Please read CONTRIBUTING.md first.

📄 License

MPL-2.0 - see LICENSE for details.

🙏 Acknowledgments

Built with the Baryo.Dev philosophy: zero dependencies, minimal allocations, safe by default.


Made with ❤️ by Baryo.Dev

📊 Performance

Speed is not the pitch. Per successful call, both Carom and Polly cost nanoseconds, invisible next to the network or database call being wrapped. What Carom offers is small, allocation-free, dependency-free resilience for hosts where the standard stack is too much: .NET Framework and netstandard2.0 services, size-constrained deployments, and libraries that should not impose a dependency graph.

The claims we do make are measured (Apple M1, .NET 8, against Polly 8.4.2) and enforced by tests/Carom.Tests/PublishedClaimsTests.cs:

  • Zero allocations on the successful hot path: Carom 0 B per call. Polly v8 allocates 24 B per call, the Polly v7 API 248 B.
  • Small on disk: Carom.dll is 21.5 KB and Carom.Extensions.dll 53.5 KB. Polly.Core.dll (net8.0) is 237 KB.
  • Zero package dependencies on every target: Polly.Core has none on net8.0 but needs four packages on netstandard2.0 and five on .NET Framework.

Details and methodology in docs/BENCHMARKS.md.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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 was computed.  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 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages (6)

Showing the top 5 NuGet packages that depend on Carom:

Package Downloads
Carom.Extensions

Advanced resilience patterns for Carom: Circuit Breaker, Fallback, Bulkhead, and Rate Limiting. Zero external dependencies. Lock-free implementations for maximum performance. Extends Carom core with production-grade patterns.

Carom.Http

HTTP integration for Carom resilience library. Provides DelegatingHandler for automatic retry on transient HTTP errors (503, 408, 429, 504, 502). Integrates seamlessly with HttpClientFactory and ASP.NET Core.

Carom.EntityFramework

Entity Framework Core integration for Carom resilience library. Provides automatic retry for transient database errors with EF Core DbContext.

Carom.Telemetry.OpenTelemetry

OpenTelemetry instruments for the Carom resilience library. Provides meters, counters and an ActivitySource that your code calls to record retries, circuit breaker opens, bulkhead rejections and rate limit rejections. Carom does not emit these automatically yet; see the repository issues.

Carom.AspNetCore

ASP.NET Core integration for Carom resilience library. Provides middleware for request resilience, health checks, and configuration integration.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 170 9/3/2026
1.7.0 192 8/28/2026
1.6.0 193 8/28/2026
1.5.0 331 7/13/2026
1.1.0 287 2/25/2026
1.0.2 281 1/19/2026
1.0.1 278 1/5/2026
1.0.0 281 12/30/2025