Dispatch
1.x
Docs/Dispatch/Dead Letter Queue
Open

Reading1 min
Updated31 Jul 2026
Sourcev1/subsystems/dlq.mdx

The dead letter queue (DLQ) captures jobs that have permanently failed after exhausting all retry attempts.

How entries are created01

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 entries02

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/count

Replay03

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/replay

Purge04

Remove all DLQ entries:

POST /v1/dlq/purge

This is destructive and irreversible. Use with caution.

DLQ service05

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)