A watermark records how far a pipeline has processed a source, usually as the highest event timestamp or sequence number loaded so far. The next run reads only rows beyond it. A watermark should move forward only after a load commits, and boundaries need care so rows at the edge are neither dropped nor loaded twice.
For example, an incremental job stores the watermark 2026-10-14 23:59:58 after its last successful run. The next run reads source rows with an updated_at greater than that value, loads them, and only after the load commits saves the new maximum it saw. If the load fails halfway, the watermark is unchanged, and the retry reads the same rows again, which is safe if the load is idempotent.
Timestamps make imperfect watermarks. Rows committed late with an earlier timestamp, clocks that differ between servers, and many rows sharing one timestamp can all cause rows to be skipped. Common defenses are to re-read a short overlap window, such as the last ten minutes before the watermark, and remove the resulting duplicates, or to use a value that only ever increases, such as a log sequence number, when the source provides one.
In stream processing, the word has a related meaning: a watermark is the point in event time up to which the engine assumes all events have arrived, so it can close a time window and emit its result; events later than the allowed delay are dropped or handled separately. See also change data capture, late-arriving records and backfill.
Where the watermark is stored matters too. Keeping it in a small control table on the same platform, written in the same transaction as the load where possible, means the data and the record of how far it got cannot disagree after a crash. See also incremental load and partitioning.
In streaming systems, a watermark also sets how late an event may arrive and still be counted. Emolysis's Incremental append shape is built around one, and its template takes the watermark column as a typed slot. See incremental load.