For the complete documentation index, see llms.txt. This page is also available as Markdown.

Outbox Archiver

Reference · Applies to Brighter V10 · Prerequisites: Outbox Support

The Outbox Archiver is a background service that monitors an Outbox and moves messages older than a certain age into long-term storage, keeping your Outbox small. It is the clean-out stage of the Outbox life-cycle: the Sweeper dispatches messages, and the Archiver later retires the ones that have been sent.

Like the Sweeper, the Archiver should run as a singleton — only one Archiver per Outbox at a time. It shares the same distributed lock mechanism, taking a lock on the resource named "Archiver", so the same configured opt.DistributedLock coordinates both the Sweeper and the Archiver.

You register the Archiver with UseOutboxArchiver<TTransaction>, passing an archive provider (an IAmAnArchiveProvider) and options. For a ready-made archive provider, see the Azure Archive Provider.

// ...
.UseOutboxArchiver<TransactWriteItemsRequest>(
    archiveProvider,
    opt =>
    {
        opt.MinimumAge = TimeSpan.FromHours(24);   // archive messages dispatched over a day ago
        opt.ArchiveBatchSize = 100;
    });

TTransaction is the transaction type your Outbox writes to — the same type Brighter wraps in a transaction when it stores a message — not the transaction provider you register on opt.ConnectionProvider/opt.TransactionProvider. Use the type from the column below for your store:

Outbox

TTransaction to use

Namespace

SQL Server, PostgreSQL, MySQL, SQLite, Spanner

DbTransaction

System.Data.Common

DynamoDB

TransactWriteItemsRequest

Amazon.DynamoDBv2.Model

MongoDB

IClientSessionHandle

MongoDB.Driver

Firestore

FirestoreTransaction

Paramore.Brighter.Firestore

For example, a DynamoDB Outbox uses UseOutboxArchiver<TransactWriteItemsRequest>. The DynamoDbUnitOfWork you register as the provider is not a transaction type, so UseOutboxArchiver<DynamoDbUnitOfWork> does not compile.

Timed Outbox Archiver Options

The second argument to UseOutboxArchiver<TTransaction> configures the Archiver with a TimedOutboxArchiverOptions:

Option
Type
Default
Description

TimerInterval

int

15

How many seconds the Archiver waits between checks for messages eligible for archival.

MinimumAge

TimeSpan

86400000 ms

How long since a message was dispatched before it becomes eligible for archival.

ArchiveBatchSize

int

100

How many messages the Archiver moves to the archive provider in each check.

Instrumentation

InstrumentationOptions

All

How much telemetry detail the Archiver emits.

Running the Sweeper and Archiver Out of Process

Running the Sweeper or Archiver on a background thread inside your producer application is fine for development, but in production that thread competes with your application for scheduling, and you have to take care that only one instance runs. At scale, the cleaner option is a dedicated worker executable that hosts only the Sweeper and Archiver, configured with the same external Outbox and a distributed lock. You then schedule it with your container orchestrator (Kubernetes or similar).

The worker below uses DynamoDB; swap the three fenced lines for your own database, Outbox, and lock provider.

Because the distributed lock guarantees a single active Sweeper and Archiver, you do not have to pin the deployment to a single replica. You can run several replicas for resilience, and the lock ensures only one does the work at a time:

InMemory Archive

The InMemory Archive stores dispatched messages in memory for diagnostics and replay.

When to Use the InMemory Archive

Perfect for:

  • Testing message archiving

  • Development and debugging

  • Inspecting sent messages in tests

Not recommended for production due to unbounded memory growth.

InMemory Archive Configuration

InMemory Archive Example Usage

Further Reading

Last updated

Was this helpful?