Core Building Blocks
Queue & Worker
Reliable background work with automatic retry
A queue is a background task system for deferred, durable execution. Use queues for anything that should not block the caller — image processing, report generation, data imports, email batching, or long-running workflows.
Queues have two sides:
- Queue definition — what work to do, declared on a service
- Queue worker — how to execute that work, also declared on a service
The queue itself is a named, typed contract. Commands and streams enqueue jobs, and workers pick them up. The event bridge stores the jobs durably.
Deferred execution with workers
Unlike subscriptions which react to events immediately, queues defer work and process it with dedicated workers. Unlike commands, callers do not wait for completion.
In this section
What is a Queue?
Understand queue definitions, worker lifecycle, scheduling, and result policies.
The Queue Builder
Define typed queue contracts with lifecycle config, execution profiles, and result policies.
Queue Worker
Configure worker modes, intervals, parallel handlers, and poison message policies.
HTTP Exposure
Expose queue endpoints over REST with async acceptance and status tracking.
Testing
Test queue handlers and workers with mocks, harnesses, and manual scheduling.
Quick reference
Queue lifecycle
flowchart LR
A[Command Enqueues Job] --> B[Queue Stores Job]
B --> C[Worker Picks Up]
C --> D[Run Handler]
D --> E[Complete]
D -->|Error| F[Retry?]
F -->|Yes| C
F -->|No| G[Dead Letter]
D -->|Cancel| H[Job Cancelled]
Key principles
- Queues are defined with
serviceBuilder.getQueueBuilder('name', 'description'). - Workers are defined with
serviceBuilder.getQueueWorkerBuilder('workerName', 'description').forQueue('name'). - Register both on the service builder:
.addQueueDefinition(emailQueueBuilder)and.addQueueWorkerDefinition(emailWorkerBuilder). - Commands and streams enqueue jobs via
canEnqueue('queueName', payloadSchema?). - Workers support three modes:
continuous(default),interval,sequential. context.job.complete(output?, headers?),.retry(request?),.fail(reason, fatal?),.moveToDeadLetter(reason?),.extendLease(durationMs),.cancelRequested()control job lifecycle.- Poison messages — repeated failures can pause workers after a threshold configured via
setLifecycleConfig.
EventBridge subscriptions vs QueueBridge workers
These two patterns look similar but serve different roles:
| Subscription | Queue worker | |
|---|---|---|
| Transport | EventBridge (pub/sub) | QueueBridge (work queue) |
| Competing consumers | Every subscription instance receives each event | Only one worker picks up each job |
| Job state | No job tracking | Full lifecycle: pending → active → complete/retry/dead-letter |
| Retries | Bridge-dependent | Explicit: maxAttempts, backoff, poison-message threshold |
| Use when | Reacting to events (fan-out, side effects) | Processing background work reliably (deduplication, retry, ordering) |