- Integrity: did the batch change while moving through Filament and the sink’s serialization boundary?
- Checkpoints: after an interruption, where is it safe to begin reading again?
What a batch verification proves
Filament moves rows internally as typed Arrow batches. Immediately beforeSink.Apply, the pipeline calculates a CRC32-C checksum over the batch’s Arrow
buffers, its row and column counts, and its insert/update/delete operations.
The sink recalculates that checksum at its final in-memory boundary and returns
it as WriteReceipt.WriteCRC.
batch.chunk_divergence and fails the run.
This check is sensitive to row order, column order, nulls, values, and
operations. It is not based only on row counts.
The encoded boundary
Serialization is another place data can change. Sinks that advertise encoded integrity also checksum the exact bytes handed to their transport and returnWriteReceipt.EncodedCRC. Filament requires that evidence from those sinks and
publishes batch.encoded_integrity_verified when it is present.
The two checks cover different risks:
These checks do not universally read data back from PostgreSQL, S3,
Iceberg, or another destination. Destination acknowledgement, transactions,
and read-after-write validation remain connector-specific.
How checkpoints move
Suppose an incrementalusers pipeline reads rows ordered by
(updated_at, id). Each flushed batch carries the position of its last row.
After the sink accepts the batch, Filament includes that position on the
batch.written fact. The tracker combines those deltas into the resource’s
current checkpoint.
- Run-scoped checkpoints allow the same logical run to resume a checkpointed snapshot.
- Route checkpoints carry incremental or CDC progress from one successful run to the next. They are keyed to an immutable pipeline version and route.
When progress becomes durable
When a checkpoint can be saved depends on when the sink’s work is recoverable:- If accepted batches remain recoverable after
Apply, a fully checkpointed, idempotent run can resume within the same logical run. - Incremental and CDC route checkpoints become durable only at a committed completion or committed pause boundary. A failed run does not advance what the next logical run will use.
- If a sink makes data durable only at
Commit, its progress is not saved before that commit succeeds.
What recovery looks like
For theusers example:
- The last successful run ended at
(10:30, id=42). - The next run plans a bounded incremental read starting there.
- It writes several batches, then loses its worker before commit.
- The route checkpoint remains at the last committed boundary.
- A resume may repeat already accepted rows, so an upsert sink converges by primary key instead of skipping data.