Configuration
Configure BackWave's store selection, Worker Group options (Dispatch Policy, poll interval, retries, leases), and per-Queue Concurrency Limits.
BackWave is configured where you call AddBackWave(...): you select a store,
register the generated jobs, and declare one or more Worker Groups. This
page walks the options you'll reach for most. All of it mirrors the real sample
API.
The shape of AddBackWave#
builder.Services.AddBackWave(backwave =>
{
backwave
.UseStore(_ => new PostgresJobStore(new PostgresStoreOptions { /* ... */ }))
.UseJobs(BackWaveJobs.Module);
backwave.AddWorkerGroup(new WorkerGroupOptions { /* ... */ });
});UseStore(...)selects the Storage Adapter (or the In-Memory Store when you don't need durability). See Installation for the store options.UseJobs(BackWaveJobs.Module)registers the Job Registry, a scoped handler per[Job], and the class that declares them, in one call.AddWorkerGroup(...)declares a pool of Workers. You can call it more than once; a process may host several Worker Groups.
Worker Group options#
A Worker Group is one registered pool of Workers that declares which Queues it serves and its Dispatch Policy.
backwave.AddWorkerGroup(new WorkerGroupOptions
{
Name = "strict-priority",
Policy = new DispatchPolicy.Strict(["critical", "bulk", "limited"]),
PollInterval = TimeSpan.FromMilliseconds(250),
RetryPolicy = new RetryPolicy { MaxAttempts = 5, Backoff = _ => TimeSpan.FromMilliseconds(500) },
});| Option | What it controls |
|---|---|
Name | The Worker Group's identifier. |
Policy | The Dispatch Policy: which Queue to claim from next. |
PollInterval | How often the pump polls the store for due work. Polling is the source of truth; Wake-Up Hints only cut latency. |
RetryPolicy | The attempt ceiling and backoff for jobs this group runs. |
Dispatch Policy#
A Worker Group's rule for choosing which Queue to claim from next. Both policies are work-conserving, so a worker never idles while any served Queue has due work.
-
Strict: an ordered list; earlier Queues preempt later ones, and starvation of the tail is accepted by design.
Policy = new DispatchPolicy.Strict(["critical", "bulk", "limited"]), -
Weighted: smooth weighted round-robin, deterministic with no randomness. Here
highgets six turns per one oflow:Policy = new DispatchPolicy.Weighted([("high", 6), ("low", 1)]),
Retries#
RetryPolicy sets the attempt ceiling and the backoff between attempts. An
Attempt is one execution try; a Lease expiry counts as an attempt just like
a thrown exception. When a job exhausts MaxAttempts it lands Dead-Lettered.
RetryPolicy = new RetryPolicy
{
MaxAttempts = 3,
Backoff = attempt => TimeSpan.FromMilliseconds(500),
},Per-Queue Concurrency Limits#
A Concurrency Limit is a per-Queue, cluster-wide cap on simultaneously executing jobs, enforced at claim time. It is distinct from Backpressure (a node's own pool capacity): the Concurrency Limit is one shared counter across the whole cluster for a Queue. A slot is released on terminal state or Lease expiry, never leaked by a crash. Set it through the store:
await app.Services.GetRequiredService<IJobStore>()
.SetConcurrencyLimitAsync("limited", 1);Hosting several Worker Groups#
A single process can host multiple Worker Groups (for example a Strict group for priority traffic and a Weighted group for fair sharing) without a separate worker host:
builder.Services.AddBackWave(backwave =>
{
backwave.AddWorkerGroup(new WorkerGroupOptions
{
Name = "strict-priority",
Policy = new DispatchPolicy.Strict(["critical", "bulk"]),
RetryPolicy = new RetryPolicy { MaxAttempts = 5 },
});
backwave.AddWorkerGroup(new WorkerGroupOptions
{
Name = "weighted-fair",
Policy = new DispatchPolicy.Weighted([("high", 6), ("low", 1)]),
RetryPolicy = new RetryPolicy { MaxAttempts = 3 },
});
});Where to go next#
- Storage: the Storage Adapters and the determinism boundary they sit on.
- Dashboard & Operations: Dashboard Permissions and Operator Actions for running BackWave in production.
- Virtual-Time Testing: assert on exactly what ran.