DE//AGENT
Explore
Tutorial Lesson 4 of 10 · The Reliability Series community intermediate

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

  1. Retries and backfills duplicate or corrupt data because writes are appends. (from pattern-idempotent-partition-overwrite )
  2. 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 )
  3. 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 )
  4. Every task writes to a partition keyed by the logical date, or uses MERGE. (from skill-airflow-dag-reviewer )
  5. A re-run is only safe if the task is idempotent — check before clearing. (from runbook-pipeline-failed )
  6. Make every task idempotent so a re-run is always safe, and retry with backoff. (from runbook-pipeline-failed )
  7. 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