Menu

Topic 1 of 8

Idempotency And Backfills

Learn Idempotency And Backfills for free with explanations, exercises, and a quick test (for Data Architect).

Published: January 18, 2026 | Updated: January 18, 2026

Why this matters

As a Data Architect, you must ensure data pipelines can be re-run without corrupting data and that historical corrections (backfills) are safe, fast, and verifiable. Real tasks you will face:

  • Designing pipelines that can reprocess a day, month, or the entire history without creating duplicates.
  • Defining unique keys and MERGE strategies for facts and dimensions.
  • Choosing partitioning and watermarking for incremental loads.
  • Running backfills after schema changes, late-arriving data, or logic fixes, with rollback plans.
  • Validating outcomes with row-level checks and aggregate reconciliations.

Concept explained simply

Idempotency

Idempotency means: running the same job multiple times produces the same final state. If your job is idempotent, retries or backfills do not multiply rows, inflate metrics, or lose updates.

  • In practice: use deterministic keys, deduplicate before writing, and write with upsert/merge or partition-overwrite semantics.
  • Target: exactly-once outcomes, even if the runtime is at-least-once.

Backfills

Backfills are controlled reprocessing of historical data to fix errors, apply new logic, or load missed data. Safe backfills are:

  • Scoped (by partition or time range),
  • Repeatable (can re-run without harm),
  • Observable (validated with metrics and samples),
  • Reversible (rollback plan exists).

Mental model

Think “ledger vs snapshot”

Two ways to reach the same truth:

  • Ledger model: apply events in order with dedupe; replays should converge to the same state (idempotent consumption).
  • Snapshot model: rebuild a full, correct partition and replace the old one atomically (idempotent replacement).

Pick the model per table and stick to it to keep your backfills predictable.

Core building blocks

  • Business keys: stable, deterministic identifiers (e.g., order_id + line_id). Avoid using random or run-specific IDs.
  • Dedupe windows: remove duplicates using ROW_NUMBER() over business key ordered by event time or source commit time.
  • UPSERT/MERGE: update when matched and insert when not. Compare hashes to update only when fields changed.
  • Partition overwrite: rebuild a full partition and atomically replace it to guarantee idempotency.
  • Watermarks: track the last processed event time or source position (e.g., LSN). Support late data with a small lag window.
  • Change data capture (CDC): order by source commit time; apply upsert/delete with last-write-wins or true source ordering.
  • Soft deletes: model deletes as is_active=false for simpler idempotency and auditability.
  • Validation: row counts by partition, distinct key counts, checksums/hashes, sample spot checks.

Worked examples

Example 1: Idempotent fact load with MERGE

Scenario: load daily order_lines into a fact table.

  1. Dedupe: keep the newest record per (order_id, line_id) using event_time.
  2. MERGE on (order_id, line_id).
  3. Update only if changed: compare a hash of relevant fields to avoid churn.
  4. Soft-delete when canceled.
WITH src AS ( ... ),
src_dedup AS (
  SELECT *,
         ROW_NUMBER() OVER (PARTITION BY order_id, line_id ORDER BY event_time DESC) AS rn
  FROM src
)
MERGE INTO fact_order_lines t
USING (SELECT * FROM src_dedup WHERE rn=1) s
ON (t.order_id=s.order_id AND t.line_id=s.line_id)
WHEN MATCHED AND (t.row_hash != s.row_hash OR t.is_active != s.is_active) THEN
  UPDATE SET qty=s.qty, price=s.price, is_active=s.is_active, row_hash=s.row_hash, updated_at=CURRENT_TIMESTAMP
WHEN NOT MATCHED THEN
  INSERT (order_id,line_id,qty,price,is_active,row_hash,created_at)
  VALUES (s.order_id,s.line_id,s.qty,s.price,s.is_active,s.row_hash,CURRENT_TIMESTAMP);

Re-running yields the same final state: idempotent.

Example 2: Partition overwrite for a day

Scenario: rebuild metrics for 2025-06-01.

  1. Recompute the full day in a staging table.
  2. Validate counts and key uniqueness.
  3. Atomically overwrite the 2025-06-01 partition in the target table.

Re-running replaces the partition with identical data, so the outcome is stable.

Example 3: CDC backfill after logic fix

Scenario: a CDC dim_customer missed address changes for two months.

  1. Extract source changes for the missed period ordered by commit_time.
  2. Apply MERGE with last-write-wins based on commit_time, not ingestion_time.
  3. Validate net record counts and sample customers across the period.

Idempotency is achieved via deterministic ordering and MERGE on business key.

Example 4: Watermark with late data

Scenario: process events with event_time and up to 3-day lateness.

  1. Maintain high watermark of event_time processed.
  2. Each run processes [watermark - 3d, now], then advances watermark to (now - 3d).
  3. Deduplicate on event_id to avoid repeats; use MERGE or partition overwrite.

Re-runs will see the same window and converge to the same state.

Exercises

These mirror the graded exercises below. Do them here first, then submit in the Exercises section for feedback.

Exercise 1: Design an idempotent MERGE for order_lines

Goal: write an upsert that is safe to re-run.

Input fields: order_id, line_id, qty, price, canceled_flag, event_time

  • Deduplicate by (order_id, line_id) keeping latest event_time.
  • Soft-delete when canceled_flag=true (is_active=false).
  • Update only if changed (use a row_hash).

Deliverable: a MERGE statement and a brief note explaining why it is idempotent.

Exercise 2: Plan a safe August 2024 backfill

Dataset: events partitioned by dt=YYYY-MM-DD on storage. Keys: event_id (unique), event_time. Target table currently contains June–September.

  • Backfill scope: 2024-08-01 to 2024-08-31.
  • Assume up to 2-day late arrivals.

Deliverable: a step-by-step plan including batching, isolation, validation, and rollback.

  • I identified the business keys.
  • I included dedupe and a deterministic write strategy.
  • I documented validation metrics and rollback.

Common mistakes and how to self-check

  • Using random IDs per run: breaks idempotency. Self-check: can I re-run without increasing row count?
  • No dedupe before merge: duplicate source rows cause churn. Self-check: enforce ROW_NUMBER()=1 per key.
  • Updating when nothing changed: unnecessary rewrites. Self-check: compare row_hash to skip no-op updates.
  • Choosing ingestion_time as watermark when business logic needs event_time: late data lost. Self-check: simulate late arrivals; do metrics remain correct?
  • Backfilling without isolation: users see partial data. Self-check: use staging/shadow tables and atomic swap/partition overwrite.
  • No rollback plan: risky. Self-check: snapshot target or keep last N versions to revert.

Self-check before running a backfill

  • Scope is precise (partitions/time range listed).
  • Write path is idempotent (merge/overwrite documented).
  • Dedupe keys and order (event_time or commit_time) are defined.
  • Validation queries and acceptance thresholds are written.
  • Rollback plan and timebox are defined.
  • Stakeholders informed about window of change.

Practical projects

  • Build an idempotent ingestion pipeline: file -> staging -> warehouse with MERGE and backfill for one month.
  • Add late-data handling: watermark with a 2-day lag; measure the impact on final metrics.
  • Create a backfill playbook: a template with steps, queries, and checklists your team can reuse.

Who this is for

Data Architects, Senior Data Engineers, and Platform Engineers who design and operate ETL/ELT systems and need reliable reprocessing.

Prerequisites

  • Comfort with SQL (including MERGE/UPSERT, window functions).
  • Basic understanding of partitions, file formats, and batch/streaming concepts.
  • Familiarity with source systems (e.g., CDC, APIs, event streams).

Learning path

  1. Understand keys and dedupe patterns.
  2. Practice MERGE and partition-overwrite strategies.
  3. Implement watermarks and late-data policies.
  4. Run a small, scoped backfill with full validation.
  5. Document and automate your backfill process.

Next steps

  • Automate a daily partition overwrite job for a derived table.
  • Add job-level idempotency checks (e.g., no-op detection, idempotency tokens).
  • Introduce a sandbox backfill workflow with approval and rollback gates.

Mini challenge

You discover a pricing bug affecting 7 days of sales facts. Outline a plan that includes: isolation, recomputation scope, validation queries (three checks), and rollback. Keep it to 10 steps or fewer.

Quick test and progress

The quick test is available to everyone. Sign in to save your progress and resume later.

Practice Exercises

2 exercises to complete

Instructions

Write an idempotent MERGE that loads order_lines into fact_order_lines.

Source fields: order_id, line_id, qty, price, canceled_flag, event_time.

  • Dedupe by (order_id, line_id) using latest event_time.
  • Compute row_hash over (qty, price, canceled_flag).
  • Set is_active=false when canceled_flag=true; else true.
  • Only UPDATE when something changed (row_hash differs) or active flag differs.

Explain in 2–3 sentences why your approach is idempotent.

Expected Output
A MERGE statement that can be re-run without creating duplicates or unnecessary updates; explanation of idempotency.

Idempotency And Backfills — Quick Test

Test your knowledge with 8 questions. Pass with 70% or higher.

8 questions70% to pass

Have questions about Idempotency And Backfills?

AI Assistant

Ask questions about this tool