Axon Docs
GitHub Quickstart

Docs / Guides

Priority and queues

Two independent ways to control which job runs next, and on which worker fleet.

Priority

Shift a job's dispatch order with PriorityLow, Medium (the default), High, or Critical:

RotateKeys.cs
var jobId = await axonClient.EnqueueAsync<MyClass>(x => x.RotateSecurityKeys(),
    new AxonEnqueueOptions { Priority = JobPriority.Critical });

This isn't a hard tier — a flood of High jobs can't starve a Low job forever. Each priority level gets a fixed boost, a free head start (in minutes of virtual age) applied when jobs are sorted for dispatch:

PriorityBoostBeats a Low job younger than
Low0
Medium5 min5 minutes old
High15 min15 minutes old
Critical60 min1 hour old

A job's real age plus its boost decides dispatch order, so a High job only cuts ahead of an already-waiting Low job by up to 15 minutes — a Low job that's been waiting longer than that still goes first. If nothing else is competing for a dispatch slot, priority makes no difference at all: the boost only matters under contention. A lone Low job still dispatches on the very next poll.

Worked example: a High job created 1 minute ago dispatches before a Low job created 1 minute ago (High's 15-minute boost outweighs the tiny age difference), but a Low job created 20 minutes ago still dispatches before that same 1-minute-old High job — 20 real minutes beats a 15-minute boost.

Queues

Route a job through a named queue instead of the implicit "default" one:

ChargeInvoice.cs
var jobId = await axonClient.EnqueueAsync<MyClass>(x => x.ChargeInvoice(invoiceId),
    new AxonEnqueueOptions { QueueName = "billing" });

An Axon.Server instance only claims/dispatches jobs on queues it was registered for, via .AddQueues(...) chained off AddAxonServer():

Program.cs
builder.Services.AddAxonServer()
    .AddAxonDashboard()
    .AddQueues("billing"); // this instance serves "billing" AND "default"

.AddQueues(...) always adds "default" alongside whatever you pass — it's never an exclusive allowlist, so calling .AddQueues("billing") doesn't stop an instance from also running ordinary unqueued jobs. An instance that never calls .AddQueues(...) at all still serves "default".

A job on a queue no live instance serves simply sits waiting — same as a job whose target device is offline — until an instance that serves it comes online. This is purely an in-process routing decision in Axon.Server; no store schema or locking is involved, unlike priority or concurrency limits.