Long-running queues
Long-running backend work belongs to queue workers. A long-running queue acknowledges after terminal success and keeps ownership alive with heartbeats and lease extensions.
ts
const queue = service
.getQueueBuilder('billing.monthlyClosing', 'Close a monthly billing cycle')
.addPayloadSchema(billingClosingQueuePayloadSchema)
.addParameterSchema(billingClosingQueueParameterSchema)
.setExecutionProfile('longRunning', {
maxRuntimeMs: 6 * 60 * 60_000,
})The long-running profile is a safer shorthand over lifecycle settings:
- five minute visibility timeout
- one minute heartbeat
- automatic lease extension
- derived max lease extensions from
maxRuntimeMs - bounded attempts and retry window
- graceful shutdown policy that lets unsettled leases expire
Handlers must still be idempotent. PURISTA provides at-least-once execution, not exactly-once execution.
Bridge limitations matter:
DefaultQueueBridgesupports leases and lease extension in-memory, but jobs and leases are lost on process restart.- Redis and NATS queue bridges persist jobs, support lease recovery, and are the better fit for production long-running jobs.
strict: trueon the long-running profile fails startup when the selected queue bridge cannot advertise the required capability.idempotencyEnforcementis currentlyfalsefor the shipped queue bridges, so strict transport-level dedupe is not promised in v1.
For lower-level tuning, see Queue internals & delivery tuning.
