Idempotency and reruns — make every task safe to run twice
Retries are inevitable, so a task that appends duplicates rows every time it is cleared: hold each task to the idempotency test, replace its partition atomically instead of appending, and assert the invariant in CI with a test that runs the same date twice.
At a glance
| When | Wiring retries onto any task that writes; Preparing a pipeline you will need to backfill |
|---|---|
| Where | Reliability |
| Why | Retries are inevitable, so a task that is not idempotent turns every retry into a duplicate — make each run replace its partition atomically instead of appending. |
Learning objectives
- Apply the idempotency test to every task before trusting retries
- Replace appends with atomic partition overwrites keyed by the logical date, or MERGE
- Assert idempotency in CI with an invariant test on row counts
What you need
- A batch job that can be cleared and retried
- A logical date or partition key per run
- [object Object]
Steps
- Retries and backfills duplicate or corrupt data because writes are appends. (from pattern-idempotent-partition-overwrite )
- Hold every task to the idempotency test — "If this task runs twice for the same logical date, is the output the same?" If no, fix it before anything else — retries will happen. (from skill-airflow-dag-reviewer )
- Make each run write the complete result for its logical partition and replace that partition atomically — `INSERT OVERWRITE partition(dt=...)` or Delta/Iceberg replace-where. The invariant — running the same date twice yields identical output. (from pattern-idempotent-partition-overwrite )
- Every task writes to a partition keyed by the logical date, or uses MERGE. (from skill-airflow-dag-reviewer )
- A re-run is only safe if the task is idempotent — check before clearing. (from runbook-pipeline-failed )
- Make every task idempotent so a re-run is always safe, and retry with backoff. (from runbook-pipeline-failed )
- Assert invariants, not snapshots — count(*) is stable across a re-run (idempotency), no nulls in the grain key, sum(revenue) equals the source sum within tolerance. (from skill-pipeline-test-author )
Check yourself
- Running the same logical date twice yields identical output — proven by a CI test that asserts count(*) is stable across a re-run.
- No task appends to a partition it can recompute.
Worked example
The idempotency test — from skill-airflow-dag-reviewer
"If this task runs twice for the same logical date, is the output the same?"
If no, fix it before anything else — retries will happen.
The invariant list for the harness — from skill-pipeline-test-author
- `count(*)` is stable across a re-run (idempotency)
- no nulls in the grain key
- sum(revenue) equals the source sum within tolerance
- a quarantined row never appears in the published table
The atomic overwrite — from pattern-idempotent-partition-overwrite
Make each run write the complete result for its logical partition and replace
that partition atomically. Never append to a partition you can recompute.
`INSERT OVERWRITE partition(dt=...)` or Delta/Iceberg replace-where do this.
Sourced from
Security scan
Last sweep 2026-10-24: 0 finding(s), 0 marked as examples.
Common gotchas
- Retries and backfills duplicate or corrupt data because writes are appends.
- A re-run is only safe if the task is idempotent — check before clearing.
- Idempotency costs an upsert/overwrite pattern on every write — pay it once and retries become routine.
Production considerations
- Idempotent tasks turn incidents into routine re-runs.
- If a test needs the network or a running warehouse, it is not a unit test — keep the invariant harness offline.
Diagram
idempotent reruns
|
|- idempotency test --> "same logical date twice, same output?"
|
|- append --> duplicates on retry (the bug)
|- INSERT OVERWRITE partition / MERGE --> atomic replace (the fix)
|
|- CI invariant --> count(*) stable across re-run
Registry stats
| Verification | community · Oct 23, 2026 |
|---|---|
| Completeness | 81 |
| Trust multiplier | ×1.25 |
| Composite | 34.15 · adequate |
| Freshness | 1 days since last source check |
| Difficulty | intermediate |
| Version | 0.1.0 |
| License | CC-BY-4.0 |
| Security flags | none |
Did this solve your problem?
Idempotency and reruns — make every task safe to run twice