← Back to Backend Reliability

Backend Reliability

Background Jobs Must Be Idempotent and Safe to Retry

Any background job can be retried by the queue on failure. If the job is not idempotent, retries cause duplicate side effects like double emails or double charges.

Rule

Every background job must produce the same outcome when replayed with the same input.

Why

Queue processors guarantee at-least-once delivery. Without idempotency, receiver-side retries corrupt data.

Must

  • Assign a stable job ID to every enqueued task.
  • Check whether the job has already succeeded before executing its side effects.
  • Record job completion atomically with its side effects where possible (database transaction).
  • Mark jobs as failed with reason after max retry attempts.

Should

  • Use a dead-letter queue for jobs that exhaust retries.
  • Alert on dead-letter queue depth.

Anti-patterns

  • Job that sends an email without checking if it was already sent.
  • Unbounded retries with no backoff.

Test Cases

  • Replaying a completed job produces no additional side effects.
  • Job exhausting retries moves to dead-letter queue.

Telemetry

  • job_started
  • job_completed
  • job_skipped_already_processed
  • job_dead_lettered