Skip to content

Retry & Dead Letter Queue ​

Retry Policies ​

GrydJobs uses Polly for retry policy management.

How Retries Work ​

  1. A job fails with an exception
  2. GrydJobs checks the retry policy configured for that job type
  3. If retries remain, the job is re-enqueued after the backoff delay
  4. If all retries are exhausted, the job is moved to the Dead Letter Queue

Configuration ​

csharp
builder.Services.AddGrydJobs(options =>
{
    // Default policy for all jobs
    options.DefaultRetryPolicy = new RetryPolicyOptions
    {
        MaxRetries = 3,
        InitialDelay = TimeSpan.FromSeconds(10),
        BackoffType = BackoffType.Exponential
    };

    // Per-job overrides
    options.RetryPolicies
        .Register<CriticalJob>(maxRetries: 10, delay: TimeSpan.FromMinutes(1))
        .Register<IdempotentJob>(maxRetries: 20, delay: TimeSpan.FromSeconds(5));
});

Retry Timeline Example (Exponential Backoff) ​

AttemptDelayTotal Elapsed
1st retry10s10s
2nd retry20s30s
3rd retry40s1m 10s
4th retry80s2m 30s
5th retry160s5m 10s

Dead Letter Queue ​

Jobs that exhaust all retry attempts are automatically moved to the Dead Letter Queue (DLQ).

DLQ Entry Contents ​

Each dead letter entry preserves:

  • Original job ID — reference to the source job
  • Job type name — the .NET type of the failed job
  • Error details — last error message and stack trace
  • Reason — why the job was dead-lettered (MaxRetriesExceeded, Timeout, Manual)
  • Attempt count — total number of execution attempts
  • Timestamps — original enqueue time and dead-letter time
  • Correlation ID — for distributed tracing
  • Tenant ID — for multi-tenant isolation

Inspecting the DLQ ​

http
GET /api/v1/dead-letter-jobs?page=1&pageSize=20

Response:

json
{
  "items": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "originalJobId": "ext-12345",
      "jobTypeName": "MyApp.Jobs.ImportDataJob",
      "lastErrorMessage": "Connection timeout after 30s",
      "reason": "MaxRetriesExceeded",
      "totalAttempts": 5,
      "deadLetteredAt": "2026-02-18T14:30:00Z"
    }
  ],
  "totalCount": 1,
  "pageNumber": 1,
  "pageSize": 20
}

Retrying Dead Letter Jobs ​

Retry a single job:

http
POST /api/v1/dead-letter-jobs/{id}/retry

Purging the DLQ ​

Remove old entries:

http
POST /api/v1/dead-letter-jobs/purge
Content-Type: application/json

{ "retentionDays": 30 }

Automatic Cleanup ​

GrydJobs includes a background service that automatically purges DLQ entries older than DeadLetterRetentionDays:

csharp
options.DeadLetterRetentionDays = 30; // Auto-purge after 30 days
options.DeadLetterRetentionDays = null; // Disable auto-purge

Released under the MIT License.