Dead Letter Queue
Failed job management, inspection, replay, and purge.
The dead letter queue (DLQ) captures jobs that have permanently failed after exhausting all retry attempts.
How entries are created
When a job's RetryCount reaches MaxRetries and the handler still returns an error, the executor calls dlq.Service.Push to create a DLQ entry preserving the full context:
- Original job name, queue, and payload
- Final error message
- Total retry count and max retries
- Scope app/org IDs
The job state is set to failed and an ext.JobDLQ event fires.
Listing DLQ entries
entries, err := eng.DLQService().DLQStore().ListDLQ(ctx, dlq.ListOpts{
Limit: 50,
Offset: 0,
})Or use the admin API:
GET /v1/dlq
GET /v1/dlq/:entryId
GET /v1/dlq/countReplay
Replay re-enqueues a DLQ entry as a new pending job with the original payload. The ReplayedAt field is set on the DLQ entry.
Via admin API:
POST /v1/dlq/:entryId/replayPurge
Remove all DLQ entries:
POST /v1/dlq/purgeThis is destructive and irreversible. Use with caution.
DLQ service
The dlq.Service is accessible via the engine:
svc := eng.DLQService()
// Push is called automatically by the executor.
svc.Push(ctx, failedJob, err)
// Access the store directly for list/count/purge.
svc.DLQStore().ListDLQ(ctx, opts)
svc.DLQStore().PurgeDLQ(ctx)