Philiprehberger.Outbox 0.2.1

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

Philiprehberger.Outbox

CI NuGet Last updated

Transactional outbox pattern implementation for reliable event/message publishing.

Installation

dotnet add package Philiprehberger.Outbox

Usage

using Philiprehberger.Outbox;

builder.Services.AddOutbox(options =>
{
    options = options with
    {
        PollingInterval = TimeSpan.FromSeconds(10),
        BatchSize = 50,
        MaxRetries = 5
    };
});

builder.Services.AddSingleton<IOutboxStore, MyEfCoreOutboxStore>();
builder.Services.AddSingleton<IOutboxDispatcher, MyRabbitMqDispatcher>();

Saving Messages

using Philiprehberger.Outbox;

var message = new OutboxMessage(
    Id: Guid.NewGuid(),
    Type: "OrderPlaced",
    Payload: JsonSerializer.Serialize(order),
    CreatedAt: DateTimeOffset.UtcNow);

await outboxStore.SaveAsync(message);

Message Priority

using Philiprehberger.Outbox;

var urgent = new OutboxMessage(
    Id: Guid.NewGuid(),
    Type: "PaymentFailed",
    Payload: JsonSerializer.Serialize(payment),
    CreatedAt: DateTimeOffset.UtcNow,
    Priority: MessagePriority.Critical);

await outboxStore.SaveAsync(urgent);

Deduplication with Idempotency Keys

using Philiprehberger.Outbox;

var message = new OutboxMessage(
    Id: Guid.NewGuid(),
    Type: "OrderPlaced",
    Payload: JsonSerializer.Serialize(order),
    CreatedAt: DateTimeOffset.UtcNow,
    IdempotencyKey: $"order-placed-{order.Id}");

await outboxStore.SaveAsync(message);

Dead Letter Queue

using Philiprehberger.Outbox;

// Default in-memory DLQ is registered automatically.
// Replace with your own implementation for production:
builder.Services.AddSingleton<IDeadLetterStore, MyDatabaseDeadLetterStore>();

// Inspect dead-lettered messages:
var dlq = serviceProvider.GetRequiredService<IDeadLetterStore>();
var failed = await dlq.GetAllAsync();

Diagnostic Events

using Philiprehberger.Outbox;

OutboxDiagnostics.MessageDispatched += msg =>
    Console.WriteLine($"Dispatched: {msg.Id} ({msg.Type})");

OutboxDiagnostics.MessageDeadLettered += msg =>
    Console.WriteLine($"Dead-lettered: {msg.Id} after {msg.RetryCount} retries");

API

OutboxMessage

Property Type Default Description
Id Guid Unique message identifier
Type string Message type discriminator
Payload string Serialized message payload (JSON)
CreatedAt DateTimeOffset When the message was created
ProcessedAt DateTimeOffset? null When the message was dispatched
Error string? null Last failure error message
RetryCount int 0 Number of dispatch attempts
IdempotencyKey string? null Deduplication key (duplicates are skipped)
Priority MessagePriority Normal Dispatch priority level

MessagePriority

Value Description
Low Dispatched after all higher-priority messages
Normal Default priority
High Dispatched before Normal and Low
Critical Dispatched before all other messages

IOutboxStore

Method Description
SaveAsync(message, ct) Persist a new outbox message
GetPendingAsync(batchSize, ct) Retrieve unprocessed messages
MarkProcessedAsync(id, ct) Mark a message as dispatched
MarkFailedAsync(id, error, ct) Mark a message as failed

IOutboxDispatcher

Method Description
DispatchAsync(message, ct) Dispatch a message to its destination

IDeadLetterStore

Method Description
AddAsync(message, ct) Add a failed message to the dead letter queue
GetAllAsync(ct) Retrieve all dead-lettered messages

OutboxOptions

Property Type Default Description
PollingInterval TimeSpan? 5 seconds How often the relay polls for pending messages
BatchSize int 100 Max messages per polling cycle
MaxRetries int 3 Max dispatch attempts before dead-lettering

OutboxDiagnostics

Event Description
MessageEnqueued Raised when a message is saved to the outbox
MessageDispatched Raised when a message is successfully dispatched
MessageFailed Raised when a dispatch attempt fails
MessageDeadLettered Raised when a message is moved to the dead letter queue

OutboxServiceCollectionExtensions

Method Description
AddOutbox(configure?) Register the outbox relay service, options, and default DLQ

Development

dotnet build src/Philiprehberger.Outbox.csproj --configuration Release

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
0.2.1 119 4/1/2026
0.2.0 116 3/28/2026
0.1.7 109 3/27/2026
0.1.6 108 3/25/2026
0.1.5 106 3/25/2026
0.1.4 108 3/23/2026
0.1.3 109 3/17/2026
0.1.2 116 3/16/2026
0.1.1 110 3/16/2026
0.1.0 113 3/16/2026