Idempotent background jobs
This course works through how to make a background job safe to run more than once, using Partners::FetchSiteIconJob as the running example. It compares a guard checked at enqueue time with one checked inside perform. It then covers three tools for a single step: a state check, a unique index with create_or_find_by!, and absolute writes. A hypothetical second step shows where one guard breaks. The course then adds a reservation row written before the side effect, step ordering, and HTTP GET versus POST with a deduplication key.
What you'll learn
- ✓Why a guard inside perform protects retries and an enqueue-time check does not
- ✓Three ways to make one step safe to redo: state checks, unique indexes and absolute writes
- ✓Tracing every crash point between two effects in a job
- ✓Guarding a step with a reservation row under a unique index, written before the side effect
- ✓Why placing the least-safe step last limits damage from a missing guard
- ✓How GET differs from external POST requests that need a deduplication key
One guard was never the whole job
Two courses already pointed here by name. The mid-level course "Pattern: idempotency keys" built a reserve, work, complete guard around a whole operation, and closed by describing this one: "That course asks a harder question: how to design a job so it's safe to retry any number of times, including…
Read the full lesson free →Curriculum
7 lessonsOne guard was never the whole job
Shows why FetchSiteIconJob stays idempotent with one attached? check, and why the check inside perform matters most.
Three ways to make one step safe to redo
Covers checking state before acting, letting a unique index refuse duplicates, and writing absolute end states instead of relative changes.
A job with two things to do
Adds a hypothetical email step and traces each crash point to show one guard skipping the second step.
The step you can't guard with a state check
Guards the email step with a reservation row under a unique index, created before the side effect runs.
Put the unsafe step last
Explains why placing the least-safe step last turns a duplicated effect into a delayed one when guards are missing.
Idempotent by the rules, and idempotent by agreement
Contrasts GET, idempotent by the HTTP specification, with external POST requests that need a key the receiver deduplicates on.
Putting it together: a job that can die anywhere and still be right
Walks through the finished job step by step and lists which steps need a guard and which need nothing.