Writing Idempotent Transformations

SkillDev tools

Write data transformations and loads that produce the same result no matter how many times they run, using MERGE/upsert, deterministic partition overwrites, deduplication, and stable keys. Use when a retry could duplicate data, a job is not safe to re-run, a pipeline needs exactly-once effects, or loads must be backfill-safe.

Available today. Use it from your connected AI after setup.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Then ask your AI: use the Writing Idempotent Transformations skill

What this skill tells your AI

The instructions your AI receives, as published by unknown-333/awesome-data-engineering-skills in skills/writing-idempotent-transformations/SKILL.md and read by ahel’s review.

When to use

  • A task may be retried (orchestrator retries, manual re-runs, replays).
  • A backfill must not change already-correct numbers or create duplicates.
  • You are writing an incremental load, upsert, or partition refresh.
  • Do NOT use for one-off exploratory queries with no persisted side effects.

Why it matters

Failures are normal. Retries, backfills, and replays run the same logic again. If a job is idempotent, running it once or five times yields the same final state — so recovery is safe and boring. If not, retries duplicate rows and backfills silently change history. This is the single most reported source of data incidents.

Workflow

- [ ] Define the unit of work and its natural key
- [ ] Make writes overwrite-by-key or overwrite-by-partition (never blind append)
- [ ] Remove dependence on wall-clock time / autoincrement / random order
- [ ] Verify: running twice == running once (row counts and checksums match)
  1. Pick a deterministic key for each output row (business key, or a hash of the identifying columns).
  2. Replace INSERT-append with MERGE/upsert keyed on that key, or with a full partition overwrite for the window being processed.
  3. Remove non-determinism: don't key on now(), sequence values, or unordered row_number(); derive timestamps from the data/event, not the run.
  4. Test it: run the transform twice on the same input and assert identical output (count + checksum).

Patterns

Delete-insert by partition — the simplest idempotent load for a time window: delete the target partition, then insert its freshly computed rows in one transaction. Re-running reprocesses only that window and cannot duplicate.

BEGIN;
DELETE FROM fct_orders WHERE order_date = DATE '2026-01-15';
INSERT INTO fct_orders
SELECT ... FROM staging WHERE order_date = DATE '2026-01-15';
COMMIT;

MERGE/upsert by key — when rows update in place:

MERGE INTO fct_orders t
USING staging s ON t.order_id = s.order_id
WHEN MATCHED THEN UPDATE SET amount = s.amount, status = s.status
WHEN NOT MATCHED THEN INSERT (order_id, amount, status)
VALUES (s.order_id, s.amount, s.status);

Deduplicate deterministically — keep the latest version per key with a stable tiebreaker, so the result never depends on scan order:

SELECT * FROM (
  SELECT *, ROW_NUMBER() OVER (
    PARTITION BY order_id ORDER BY updated_at DESC, source_file DESC
  ) AS rn
  FROM staging
) WHERE rn = 1;

dbt incremental — use a unique_key and merge strategy so re-runs upsert rather than append; use insert_overwrite on partitioned warehouses.

Common pitfalls

  • Blind INSERT ... SELECT in a retried task — the classic duplicate source.
  • Keying on current_timestamp/uuid() — makes every run produce new rows.
  • ROW_NUMBER() without a tiebreaker — nondeterministic when timestamps tie.
  • Appending to a partition instead of overwriting it — backfills accumulate.
  • Non-transactional delete+insert — a mid-run failure leaves the target empty; wrap both in one transaction or use atomic overwrite.

References

Signals

GitHub stars
21
Last commit
Aug 2026
Advanced
Item type
skill
Key
writing-idempotent-transformations
Source
github.com/unknown-333/awesome-data-engineering-skills