Watermarks, Made Physical
Events do not always arrive in the order they happened. A watermark is a progress estimate used to decide when to close older windows. Here, a late arrival drops at its own event time, hits an angled lid, and rolls into the left gutter. Events accepted earlier stay in their own windows when those windows close.
Watch a window close
Both events happened at 6s. The first arrives at 7s; the second at 32s. The 0–12s window closes after 30s. Advance one moment at a time.
Arrival frontier: 7s. An event arrives while its window is open. Let it reach the bottom before closing the lid.
The numbers count balls inside each container. The lid blocks every ball. Source time pauses while a ball travels, so the next deadline cannot overtake its illustrated arrival.
Now compare a whole stream
A delayed batch belongs to an earlier window. Closing sooner gives you an answer sooner; waiting longer admits more of that batch. Compare snapshots of the same 10events under two policies. Previously accepted history starts beneath any lids that have since closed.
Waiting 36 seconds longer per window admits 3 additional eventsfrom this tape.
Read the apparatus: one ball is one event, horizontal position is event time, a lid is a closed window, and the far-left bin collects late arrivals for a separate correction. Numbers over event-time bins count accepted events; the far-left number counts late events. These are totals for the selected snapshot. The sequence above shows the moments of admission and closure.
Here the watermark trails the arrival clock by the chosen lag: it estimates how far event time is complete. A larger lag leaves more windows open. Late arrivals after closure go to a separate correction; this example has no extra grace period after closure.
accepted on arrivallate eventBackfill burst: a batch replay injects old event times after newer windows have already moved on.
18s watermark lagnow 70s − lag 18s = watermark 52s
The watermark is the left edge of the shaded waiting span. A window closes when that edge passes its end.
Explore other streams and settings
Developer diagnostics
0 live bodies · 0 queued · 0ssimulation time · queued
The count you can check
Selected event
- id
- backfill-10
- event time
- 28s
- arrival
- 70s
- source
- backfill
- timeliness
- late event
- arrival watermark
- 52s
backfill-10 arrived at 70s. Its window ends at 36s; the watermark at arrival was 52s. The window was already closed, so this event was late.
Arrival order
Inspect time states and correction records
One declared time model
The replay, these explanations, and the JSON payload use the same Artifact Contract time and claim records. Event time says when a row happened; the arrival frontier says what the pipeline has seen; the watermark determines which windows can settle.
Live / open
backfill-07 occurred at 63s. At the 70s arrival frontier, the watermark is 52s and its 60–72s window remains open; completeness is provisional.
- Window
- open
- Completeness
- provisional
- Time audit
- 0 failing · 0 unknown
- Claim audit
- 0 failing · 0warning
Claim state
- provisionalThe 60–72s event-time window remains open with 1 event visible at the declared arrival frontier.
Settled
backfill-05 occurred at 45s. By the 70s arrival frontier, the 52s watermark had passed its 36–48s window; the window and completeness are both settled.
- Window
- settled
- Completeness
- settled
- Time audit
- 0 failing · 0 unknown
- Claim audit
- 0 failing · 1warning
Claim state
- supportedThe 36–48s event-time window settled with 2 events.
Late arrival / corrected
backfill-10 belongs to the 24–36s event-time window. It was visible by the 70s arrival frontier after that window settled, so the revision is backfilled, the window is corrected, and completeness is settled.
- Window
- corrected
- Completeness
- settled
- Time audit
- 0 failing · 0 unknown
- Claim audit
- 0 failing · 1warning
Claim state
- supersededBefore backfill-10 arrived, the 24–36s event-time window was reported settled with 1 event.
- supportedAfter backfill-10 arrived, the corrected 24–36s event-time window contains 2 events.
Correction watermarks:backfill:late-arrival:backfill-10 preserveswatermarks:backfill:late-corrected.claim.before-late-arrival and links it towatermarks:backfill:late-corrected.claim.after-late-arrival.
Inspect the machine-readable time payload
{ "schema": "semiotic.time-state/0.1", "scenarioId": "backfill", "referenceTime": "2026-01-01T00:01:10.000Z", "eventCount": 10, "arrivedEventCount": 10, "states": [ { "id": "live-open", "label": "Live / open", "eventId": "backfill-07", "time": { "eventTime": { "field": "eventTime", "value": "2026-01-01T00:01:03.000Z", "timezone": "UTC", "granularity": "second" }, "observedAt": "2026-01-01T00:01:03.000Z", "ingestedAt": "2026-01-01T00:01:10.000Z", "presentation": { "state": "live", "label": "Live processing state as of the 70s arrival frontier" }, "freshness": { "status": "fresh", "checkedAt": "2026-01-01T00:01:10.000Z", "heartbeatAt": "2026-01-01T00:01:10.000Z", "expiresAt": "2026-01-01T00:01:11.000Z", "basis": "The deterministic replay cursor is the declared arrival frontier." }, "watermark": { "value": "2026-01-01T00:00:52.000Z", "policy": "Arrival frontier minus 18s watermark lag", "allowedLateness": "PT0S" }, "window": { "start": "2026-01-01T00:01:00.000Z", "end": "2026-01-01T00:01:12.000Z", "status": "open" }, "completeness": { "status": "provisional", "basis": "The watermark has not passed this event-time window." }, "revision": { "status": "original" }, "sources": [ { "id": "watermarks:backfill", "kind": "stream", "label": "Deterministic event replay", "observedAt": "2026-01-01T00:01:03.000Z", "timezone": "UTC", "granularity": "second", "freshness": "fresh", "completeness": "provisional" } ] }, "claimState": { "contractVersion": "0.1", "artifact": { "id": "watermarks:backfill:live-open", "kind": "chart", "component": "EventDropChart", "title": "Live / open", "createdAt": "2026-01-01T00:01:10.000Z", "revision": "1", "configFingerprint": "sha256:d3920b8724bc40c1ab9fdffcf514db60207dcfa86ace0b2f6efe8556e125983e", "dataFingerprint": "sha256:6a8c04c9fac5999184cbc3228c6e7a55647bf4ebb160af83419c44c89ed18831" }, "claims": [ { "id": "watermarks:backfill:live-open.claim.current-window", "text": "The 60–72s event-time window remains open with 1 event visible at the declared arrival frontier.", "kind": "observation", "status": "provisional", "evidenceIds": [ "watermarks:backfill:live-open.evidence.current-window" ], "asOf": "2026-01-01T00:01:10.000Z", "authoredBy": { "kind": "system", "name": "Deterministic watermark replay" }, "scope": { "scenarioId": "backfill", "eventId": "backfill-07", "windowStartSeconds": 60, "windowEndSeconds": 72, "eventCount": 1 } } ], "evidence": [ { "id": "watermarks:backfill:live-open.evidence.current-window", "role": "source-data", "label": "Rows in the declared event-time window", "fingerprint": "sha256:6a8c04c9fac5999184cbc3228c6e7a55647bf4ebb160af83419c44c89ed18831", "dataVersion": "watermarks:backfill:live-open:current-window", "observedAt": "2026-01-01T00:01:10.000Z", "scope": { "scenarioId": "backfill", "eventId": "backfill-07", "windowStartSeconds": 60, "windowEndSeconds": 72, "eventCount": 1 }, "relationship": "descriptive" } ], "corrections": [], "audit": { "ok": true, "fail": 0, "warn": 0 } }, "audit": { "ok": true, "fail": 0, "warn": 0, "manual": 0, "unknown": 0 } }, { "id": "settled", "label": "Settled", "eventId": "backfill-05", "time": { "eventTime": { "field": "eventTime", "value": "2026-01-01T00:00:45.000Z", "timezone": "UTC", "granularity": "second" }, "observedAt": "2026-01-01T00:00:45.000Z", "ingestedAt": "2026-01-01T00:01:10.000Z", "presentation": { "state": "live", "label": "Settled event-time window through 48s" }, "freshness": { "status": "fresh", "checkedAt": "2026-01-01T00:01:10.000Z", "heartbeatAt": "2026-01-01T00:01:10.000Z", "expiresAt": "2026-01-01T00:01:11.000Z", "basis": "The deterministic replay cursor is the declared arrival frontier." }, "watermark": { "value": "2026-01-01T00:00:52.000Z", "policy": "Arrival frontier minus 18s watermark lag", "allowedLateness": "PT0S" }, "window": { "start": "2026-01-01T00:00:36.000Z", "end": "2026-01-01T00:00:48.000Z", "status": "settled" }, "completeness": { "status": "settled", "basis": "The watermark passed this event-time window." }, "revision": { "status": "original" }, "sources": [ { "id": "watermarks:backfill", "kind": "stream", "label": "Deterministic event replay", "observedAt": "2026-01-01T00:00:45.000Z", "timezone": "UTC", "granularity": "second", "freshness": "fresh", "completeness": "settled" } ] }, "claimState": { "contractVersion": "0.1", "artifact": { "id": "watermarks:backfill:settled", "kind": "chart", "component": "EventDropChart", "title": "Settled", "createdAt": "2026-01-01T00:01:10.000Z", "revision": "1", "configFingerprint": "sha256:8621b1cc93a4f86b294db154c8f1e2b8ce61b258cbc38d007305978518e8b2b1", "dataFingerprint": "sha256:c217cad72438e71e93d0c7fb5f9c75fdc1609a1d1c20b9220ec6b76371064b1e" }, "claims": [ { "id": "watermarks:backfill:settled.claim.current-window", "text": "The 36–48s event-time window settled with 2 events.", "kind": "observation", "status": "supported", "evidenceIds": [ "watermarks:backfill:settled.evidence.current-window" ], "asOf": "2026-01-01T00:01:10.000Z", "authoredBy": { "kind": "system", "name": "Deterministic watermark replay" }, "scope": { "scenarioId": "backfill", "eventId": "backfill-05", "windowStartSeconds": 36, "windowEndSeconds": 48, "eventCount": 2 } } ], "evidence": [ { "id": "watermarks:backfill:settled.evidence.current-window", "role": "source-data", "label": "Rows in the declared event-time window", "fingerprint": "sha256:c217cad72438e71e93d0c7fb5f9c75fdc1609a1d1c20b9220ec6b76371064b1e", "dataVersion": "watermarks:backfill:settled:current-window", "observedAt": "2026-01-01T00:01:10.000Z", "scope": { "scenarioId": "backfill", "eventId": "backfill-05", "windowStartSeconds": 36, "windowEndSeconds": 48, "eventCount": 2 }, "relationship": "descriptive" } ], "corrections": [], "audit": { "ok": true, "fail": 0, "warn": 1 } }, "audit": { "ok": true, "fail": 0, "warn": 0, "manual": 0, "unknown": 0 } }, { "id": "late-corrected", "label": "Late arrival / corrected", "eventId": "backfill-10", "time": { "eventTime": { "field": "eventTime", "value": "2026-01-01T00:00:28.000Z", "timezone": "UTC", "granularity": "second" }, "observedAt": "2026-01-01T00:00:28.000Z", "ingestedAt": "2026-01-01T00:01:10.000Z", "presentation": { "state": "live", "label": "Corrected after late arrival backfill-10 at 70s" }, "freshness": { "status": "fresh", "checkedAt": "2026-01-01T00:01:10.000Z", "heartbeatAt": "2026-01-01T00:01:10.000Z", "expiresAt": "2026-01-01T00:01:11.000Z", "basis": "The deterministic replay cursor is the declared arrival frontier." }, "watermark": { "value": "2026-01-01T00:00:52.000Z", "policy": "Arrival frontier minus 18s watermark lag", "allowedLateness": "PT0S" }, "window": { "start": "2026-01-01T00:00:24.000Z", "end": "2026-01-01T00:00:36.000Z", "status": "corrected" }, "completeness": { "status": "settled", "basis": "The watermark passed this event-time window." }, "revision": { "status": "backfilled", "previousArtifactId": "watermarks:backfill:before-backfill-10", "correctionId": "watermarks:backfill:late-arrival:backfill-10", "reason": "A late or replayed event changed a window that had already settled." }, "sources": [ { "id": "watermarks:backfill", "kind": "stream", "label": "Deterministic event replay", "observedAt": "2026-01-01T00:00:28.000Z", "timezone": "UTC", "granularity": "second", "freshness": "fresh", "completeness": "settled" } ] }, "claimState": { "contractVersion": "0.1", "artifact": { "id": "watermarks:backfill:late-corrected", "kind": "chart", "component": "EventDropChart", "title": "Late arrival / corrected", "createdAt": "2026-01-01T00:01:10.000Z", "revision": "2", "configFingerprint": "sha256:632d123162ce64839cf6811e622fe872e02368b57650eb79e98411bc0a492da1", "dataFingerprint": "sha256:aca72212d890d8d870c0f95ce78446634c3633379c7e3e17ba5f20a47bb5cabe" }, "claims": [ { "id": "watermarks:backfill:late-corrected.claim.before-late-arrival", "text": "Before backfill-10 arrived, the 24–36s event-time window was reported settled with 1 event.", "kind": "observation", "status": "superseded", "evidenceIds": [ "watermarks:backfill:late-corrected.evidence.before-late-arrival" ], "asOf": "2026-01-01T00:01:10.000Z", "authoredBy": { "kind": "system", "name": "Deterministic watermark replay" }, "scope": { "scenarioId": "backfill", "eventId": "backfill-10", "windowStartSeconds": 24, "windowEndSeconds": 36, "eventCount": 1 } }, { "id": "watermarks:backfill:late-corrected.claim.after-late-arrival", "text": "After backfill-10 arrived, the corrected 24–36s event-time window contains 2 events.", "kind": "observation", "status": "supported", "evidenceIds": [ "watermarks:backfill:late-corrected.evidence.current-window" ], "asOf": "2026-01-01T00:01:10.000Z", "authoredBy": { "kind": "system", "name": "Deterministic watermark replay" }, "scope": { "scenarioId": "backfill", "eventId": "backfill-10", "windowStartSeconds": 24, "windowEndSeconds": 36, "eventCount": 2 }, "supersedes": [ "watermarks:backfill:late-corrected.claim.before-late-arrival" ] } ], "evidence": [ { "id": "watermarks:backfill:late-corrected.evidence.before-late-arrival", "role": "source-data", "label": "Rows in the declared event-time window", "fingerprint": "sha256:1c0a36d032cd305b949443411182adc4fe411bd9e8d7d2e7d9d258d58b213ca5", "dataVersion": "watermarks:backfill:late-corrected:before-late-arrival", "observedAt": "2026-01-01T00:00:52.000Z", "scope": { "scenarioId": "backfill", "eventId": "backfill-10", "windowStartSeconds": 24, "windowEndSeconds": 36, "eventCount": 1 }, "relationship": "descriptive" }, { "id": "watermarks:backfill:late-corrected.evidence.current-window", "role": "source-data", "label": "Rows in the declared event-time window", "fingerprint": "sha256:aca72212d890d8d870c0f95ce78446634c3633379c7e3e17ba5f20a47bb5cabe", "dataVersion": "watermarks:backfill:late-corrected:current-window", "observedAt": "2026-01-01T00:01:10.000Z", "scope": { "scenarioId": "backfill", "eventId": "backfill-10", "windowStartSeconds": 24, "windowEndSeconds": 36, "eventCount": 2 }, "relationship": "descriptive" } ], "corrections": [ { "id": "watermarks:backfill:late-arrival:backfill-10", "reason": "A late or replayed event changed a window that had already settled.", "createdAt": "2026-01-01T00:01:10.000Z", "createdBy": { "kind": "system", "name": "Deterministic watermark replay" }, "affectedClaimIds": [ "watermarks:backfill:late-corrected.claim.before-late-arrival" ], "replacementClaimIds": [ "watermarks:backfill:late-corrected.claim.after-late-arrival" ] } ], "audit": { "ok": true, "fail": 0, "warn": 1 } }, "audit": { "ok": true, "fail": 0, "warn": 0, "manual": 0, "unknown": 0 } } ] }How it maps to Semiotic
Data rows carry an event time and an arrival time. The Artifact Contract adapter turns the replay controls into one deterministic time record; its audited window, watermark, completeness, claim, and correction fields drive the labels and inspectable payload. Bodies still drop over their event-time x-position, and closed windows add angled physics colliders. The frame animates the replay; onTick observes its progress.
import { adaptStreamTopicMetadata, auditTemporalContext, updateTemporalContext, } from "semiotic/artifact" import { EventDropChart } from "semiotic/physics" // One portable time record drives the visible labels and inspectable JSON. const liveTime = adaptStreamTopicMetadata({ id: "orders", eventTime: { field: "eventTime", value: latestEventTime, timezone: "UTC" }, ingestedAt: arrivalFrontier, watermark: { value: watermark, policy: "Arrival frontier minus an 18s lag", allowedLateness: "PT0S" }, window: { start: windowStart, end: windowEnd, status: "open" }, completeness: { status: "provisional" }, }) const correctedTime = updateTemporalContext(liveTime, { window: { start: windowStart, end: windowEnd, status: "corrected" }, completeness: { status: "settled" }, revision: { status: "backfilled", previousArtifactId: "orders-before-late-rows", reason: "Late rows changed the window", }, sources: [{ id: "orders", kind: "stream", freshness: "fresh", completeness: "settled", }], }) const timeAudit = auditTemporalContext(correctedTime, { referenceTime: arrivalFrontier, }) <EventDropChart ref={chartRef} data={arrivedEvents.map(event => ({ ...event, watermarkAtArrival: event.arrivalTime - watermarkLag - 1e-6, }))} timeAccessor="eventTime" arrivalAccessor="arrivalTime" watermarkAtArrivalAccessor="watermarkAtArrival" windows={{ size: windowSize }} watermark={{ value: arrivalFrontier - watermarkLag - 1e-6 }} timeExtent={eventTimeExtent} colorBy={classify} timeScale={8} // playback speed — higher is faster ballRadius={7.5} showProjection={false} frameProps={{ onTick, foregroundGraphics }} />