Skip to content

Idempotent Data Pipelines: Why Reruns Shouldn’t Duplicate Data

Illustration of a pipeline rerunning safely without duplicating its output data

A pipeline fails halfway through, gets rerun, and now half the rows exist twice. Idempotent data pipelines are built specifically so that rerunning the same job produces the same result, not a worse one.

What idempotency actually means here

An idempotent operation produces the same outcome no matter how many times it runs with the same input. For a data pipeline, that means rerunning a failed or interrupted job should leave the destination table in the same correct state as a single successful run, not a duplicated or partially overwritten one.

Why append-only pipelines break this by default

A pipeline that simply appends new rows on every run is the most common way idempotency quietly breaks. Run it once, get correct data. Rerun it after a partial failure, and the rows that already made it through the first time get inserted again. Nothing in an append-only design distinguishes a genuine new row from a duplicate of one that already succeeded.

How this connects to automated testing

The retail analytics warehouse and Olist analytics engineering project both run uniqueness tests as part of their automated dbt test suites. A uniqueness test failure after a rerun is often the first visible sign of a non-idempotent pipeline. The test doesn’t fix the problem, but it catches it immediately instead of letting duplicated rows sit undetected in a dashboard.

Common patterns that actually achieve idempotency

  • Full table replacement. Rebuild the entire output table on every run instead of appending. Simple and safe, at the cost of reprocessing everything each time.
  • Upserts keyed on a unique identifier. Insert new rows and update existing ones matched by key, so rerunning with the same input changes nothing.
  • Partition-based overwrite. Rebuild only the specific time partition or batch being processed, rather than the whole table, which keeps reruns cheap while staying safe.

Why this matters more with CI

A pipeline that runs through CI/CD will get rerun, sometimes automatically after a transient failure, sometimes manually while debugging. If the pipeline isn’t idempotent, every rerun carries the risk of corrupting the very data the CI pipeline was supposed to be protecting. The network intrusion detection project‘s GitHub Actions pipeline benefits from this indirectly: reproducible results depend on reruns being safe, not just possible.

A quick checklist

  1. If this pipeline failed halfway through and got rerun right now, would the output table end up correct or duplicated?
  2. Are your writes append-only, or do they upsert or replace based on a key?
  3. Do your automated tests actually check for uniqueness, or would a duplicate slip through unnoticed?
  4. Is reprocessing a single partition or batch possible, or does a rerun mean reprocessing everything?

FAQ

Is full table replacement always the simplest fix?
It’s the simplest to reason about, but it becomes expensive as data volume grows, which is when upserts or partition-based overwrites start to matter more.

Does idempotency matter for read-only queries?
Not in the same way. Idempotency is primarily a concern for writes, since a repeated read doesn’t change the state of anything.

Can a uniqueness test alone guarantee an idempotent pipeline?
No. It catches the symptom, a duplicate that already happened, but the pipeline’s write logic itself has to be designed to prevent duplication in the first place.

Related posts

Leave a comment

Your email address will not be published. Required fields are marked *