PollyAzureTableStorage 1.0.0
dotnet add package PollyAzureTableStorage --version 1.0.0
NuGet\Install-Package PollyAzureTableStorage -Version 1.0.0
<PackageReference Include="PollyAzureTableStorage" Version="1.0.0" />
<PackageVersion Include="PollyAzureTableStorage" Version="1.0.0" />
<PackageReference Include="PollyAzureTableStorage" />
paket add PollyAzureTableStorage --version 1.0.0
#r "nuget: PollyAzureTableStorage, 1.0.0"
#:package PollyAzureTableStorage@1.0.0
#addin nuget:?package=PollyAzureTableStorage&version=1.0.0
#tool nuget:?package=PollyAzureTableStorage&version=1.0.0
PollyAzureTableStorage
Polly v8 resilience for Azure.Data.Tables — add retry, timeout, and circuit-breaker to any Table Storage operation in two lines.
var tableClient = new TableClient(connectionString, "orders");
var resilient = tableClient.WithPolly(pipeline => pipeline
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromSeconds(1),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true,
ShouldHandle = TableStorageTransientErrors.IsTransient,
})
.AddTimeout(TimeSpan.FromSeconds(10)));
await resilient.UpsertEntityAsync(entity);
var response = await resilient.GetEntityAsync<OrderEntity>("partitionKey", "rowKey");
Why PollyAzureTableStorage?
Azure Table Storage throttles aggressively at scale and returns 503 during maintenance windows. Without retry logic, a single throttle event causes data loss or visible errors. This library adds Polly v8 resilience with a predicate tuned for Table Storage:
| Problem | Solution |
|---|---|
| HTTP 429 throttling (storage account IOPS limit) | Caught by TableStorageTransientErrors.IsTransient |
| HTTP 503 service unavailable during maintenance | Caught by TableStorageTransientErrors.IsTransient |
| HTTP 504 gateway timeout | Caught by TableStorageTransientErrors.IsTransient |
HttpRequestException network failure |
Caught by TableStorageTransientErrors.IsTransient |
TaskCanceledException timeout in transit |
Caught by TableStorageTransientErrors.IsTransient |
Installation
dotnet add package PollyAzureTableStorage
dotnet add package Polly.Core
Quick-start
1. Manual wiring
var client = new TableClient(connectionString, "orders");
var resilient = client.WithPolly(p => p
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromSeconds(1),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true,
ShouldHandle = TableStorageTransientErrors.IsTransient,
}));
await resilient.UpsertEntityAsync(order);
var result = await resilient.GetEntityAsync<OrderEntity>("Orders", orderId);
2. Dependency injection
builder.Services.AddPollyAzureTableStorage(connectionString, "orders", pipeline => pipeline
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromSeconds(1),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true,
ShouldHandle = TableStorageTransientErrors.IsTransient,
})
.AddTimeout(TimeSpan.FromSeconds(10)));
public class OrderRepository(ResilientTableClient client)
{
public Task UpsertAsync(OrderEntity order, CancellationToken ct)
=> client.UpsertEntityAsync(order, cancellationToken: ct);
public Task<Response<OrderEntity>> GetAsync(string pk, string rk, CancellationToken ct)
=> client.GetEntityAsync<OrderEntity>(pk, rk, cancellationToken: ct);
}
API reference
| Member | Description |
|---|---|
ResilientTableClient.Inner |
The underlying TableClient |
AddEntityAsync<T>(entity, ct) |
Adds an entity through the pipeline |
UpsertEntityAsync<T>(entity, mode, ct) |
Upserts an entity through the pipeline |
UpdateEntityAsync<T>(entity, ifMatch, mode, ct) |
Updates an entity through the pipeline |
DeleteEntityAsync(pk, rk, ifMatch, ct) |
Deletes an entity through the pipeline |
GetEntityAsync<T>(pk, rk, select?, ct) |
Gets a single entity through the pipeline |
ExecuteAsync<T>(operation, ct) |
Runs any TableClient operation through the pipeline |
TableStorageTransientErrors.IsTransient |
PredicateBuilder for 429/503/504, HttpRequestException, TaskCanceledException |
TableStorageTransientErrors.StatusCodes |
IReadOnlySet<int> — {429, 503, 504} |
client.WithPolly(pipeline) |
Wraps TableClient with a pre-built pipeline |
client.WithPolly(configure) |
Builds pipeline inline and wraps the client |
services.AddPollyAzureTableStorage(configure) |
DI registration (requires TableClient in DI) |
services.AddPollyAzureTableStorage(connStr, table, configure) |
DI with connection string shortcut |
Target frameworks
.NET 6 ✅ · .NET 8 ✅ · .NET 9 ✅
Related packages
| Package | Description |
|---|---|
| PollyAzureBlob | Polly v8 for Azure Blob Storage |
| PollyAzureServiceBus | Polly v8 for Azure Service Bus |
| PollyAzureKeyVault | Polly v8 for Azure Key Vault |
| PollyAzureEventHub | Polly v8 for Azure Event Hubs |
| PollyCosmosDb | Polly v8 for Azure Cosmos DB |
| PollyElasticsearch | Polly v8 for Elasticsearch |
| PollyRedis | Polly v8 for StackExchange.Redis |
| PollyEFCore | Polly v8 for Entity Framework Core |
| PollyDapper | Polly v8 for Dapper |
| PollyMongo | Polly v8 for MongoDB |
| PollyNpgsql | Polly v8 for Npgsql (PostgreSQL) |
| PollySqlClient | Polly v8 for Microsoft.Data.SqlClient |
| PollyGrpc | Polly v8 for gRPC |
| PollyRabbitMQ | Polly v8 for RabbitMQ |
| PollyKafka | Polly v8 for Confluent.Kafka |
| PollyOpenAI | Polly v8 for OpenAI .NET SDK |
| PollyMediatR | Polly v8 for MediatR |
| PollyHealthChecks | Polly v8 for ASP.NET Core Health Checks |
| PollyBackoff | Polly v8 backoff helpers |
License
MIT © Justin Bannister
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. 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 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 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. |
-
net6.0
- Azure.Data.Tables (>= 12.11.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Polly.Core (>= 8.7.0)
-
net8.0
- Azure.Data.Tables (>= 12.11.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Polly.Core (>= 8.7.0)
-
net9.0
- Azure.Data.Tables (>= 12.11.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Polly.Core (>= 8.7.0)
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 | 46 | 6/24/2026 |
1.0.0: Initial release. ResilientTableClient wraps Azure.Data.Tables TableClient in a Polly v8 ResiliencePipeline. Includes TableStorageTransientErrors predicate covering RequestFailedException (429, 503, 504), HttpRequestException, and TaskCanceledException. Supports net6.0, net8.0, and net9.0.