What a join is, once nothing stops
A join is normally a settled thing: two tables, a shared key, a result. Streaming joins are not settled, because the tables never finish. A service telemetry pipeline never stops emitting latency samples; a dependency graph is never in its final state; deploy events keep landing; incident feeds keep opening and closing tickets. To join any two of these — a spike in error rate against the deploy that might have caused it — you cannot wait for completeness, because completeness never arrives. You impose a window: a bounded stretch of time within which you will attempt the match, after which you commit to an answer and move on.
Windowing sounds like a housekeeping detail. It is not. It forces three explicit decisions that a batch job never has to make: what counts as "now" for the purposes of this comparison, how long to hold the question open for records that are late but not yet too late, and what happens when a straggler arrives after you have already told someone the answer. That third decision — retraction — is the one most systems try to avoid thinking about, and the one that determines whether the system's outputs can be trusted at all.
Why this sits at the top of a ladder
A Large Language Model never confronts this problem, because its corpus was collected once, frozen, and shipped. Every document in it is equally "present" in the sense that matters: none of them are still arriving. There is a training cutoff, but the model does not represent that cutoff to itself; it just answers, and the reader supplies the missing timestamp. No streams, no join, no window.
A Large World Model meets a thin version of the problem. A scene is bounded: frames from a camera and a lidar unit need to be aligned within tens of milliseconds, and the relevant window is roughly the length of the episode being modelled. Sensor fusion here is close to free — the streams are few, synchronised by hardware clocks, and the episode ends. There is a window, but it never has to be reasoned about, because it is always short and always closes on schedule.
A Large Universe Model inherits the unbounded case. Many streams, different latencies, no clock they share, no moment at which the intake stops. Belief formation about anything in such a system is structurally a join: this telemetry spike against that deploy event against yesterday's incident report against a dependency graph that has since changed shape. Windowing becomes the control surface rather than an implementation detail, because the system's only way of saying anything at all is to decide, explicitly, how long to hold a question open and under what condition an answer it already gave gets withdrawn. A system that watches everything continuously is defined less by what it takes in than by its policy for closing windows on what it has taken in so far.
This is where correctness stops being a property of an answer and becomes a property of a policy. Google's Dataflow model, published in 2015, separates the question of what is computed from where in event time it applies, when it gets materialised, and how a later refinement relates to an earlier one — accumulating, discarding, or retracting. That fourth axis exists because billing pipelines could not wait for stragglers and could not send wrong invoices. The same four questions apply, unglamorously, to a graph of services deciding whether a downstream dependency is currently safe to call.
The domain as test: an SRE trusting a dependency too long
Take the characteristic failure directly. A payments service calls an authentication service. Six months ago the authentication service had a P99 latency of 40ms and a 99.95% success rate. That reliability profile is baked into the payments team's retry budget, their circuit-breaker thresholds, their on-call runbook. Nothing in the system re-examines that assumption unless something forces it to.
Then the authentication service is quietly rearchitected — a cache layer removed, a new region added, a dependency of its own swapped out — and its reliability profile shifts. P99 climbs to 300ms under load. Nobody updates the payments team's assumptions, because those assumptions were never represented as a claim with a timestamp and a decay function. They were represented as a constant, set once, in a config file or in an engineer's memory.
The dependency graph telemetry, the deploy events, and the incident feed all contain the evidence of the change, separately, at different latencies. Deploy events log the rearchitecture instantly. Telemetry shows the latency drift over hours as traffic patterns exercise the new code paths. The incident feed only fires once someone else's timeout budget is blown and a ticket gets opened — which might be days later, once accumulated retries have started cascading. Each stream, alone, under-informs. The failure is not that any one signal was missing. It is that no join was ever attempted between them, and so no window was ever closed on the question "is this dependency still what we think it is."
An SRE inheriting this incident is not choosing between having data and not having it. They have all three streams, retained, queryable. What they lack is a standing policy that treats "this dependency is reliable" as a windowed belief rather than a fact fixed at onboarding time — one that gets rejoined against fresh telemetry on some cadence, and retracted the moment a late-arriving deploy event contradicts it.
Two objections worth taking seriously here
Just keep everything. Storage is cheap now. Retain every telemetry sample, every deploy event, every incident, forever, and join across all of it. The window was only ever a memory bound.
This is half right and cloud infrastructure makes the remaining half obvious. Kafka's log compaction and long-retention topics already let teams keep enormous histories cheaply. But retention answers a different question from the one windowing answers. At 09:14, an alert fires asking whether the authentication dependency is currently safe. You cannot answer that question with a deploy event that lands at 09:20. Something has to be said at 09:14, using whatever has arrived by 09:14, or the alerting system says nothing and the on-call engineer pages blind. Infinite storage removes the excuse that windows exist to save memory. It leaves standing the actual reason they exist: someone has to decide when to stop waiting and commit to an answer, and that decision is about time, not disk.
Dependency graphs already model this. Service meshes track dependency edges continuously and dashboards show current latency in real time. There's no missing category here, just a monitoring gap.
Concede the mechanism, dispute the framing. Most dependency graphs show the current edge, not the trajectory of belief about that edge, and almost none carry a provenance trail explaining why the edge is drawn the way it is. A dashboard reporting "P99: 300ms" right now is not the same object as a belief that says "reliability profile as of six months ago: X; superseded by deploy event at time T; confidence in supersession: high; last rejoined against telemetry: 40 minutes ago." The first is a reading. The second is an auditable, revisable claim — the kind a system needs if it is going to be trusted to decide, on its own, when a dependency's risk profile has changed enough to matter. Building that second object is exactly the windowing-plus-provenance work the streaming literature already worked out for billing pipelines, applied instead to trust between services.
What windowing buys, and what it cannot buy
None of this makes the stale-dependency failure disappear. Watermarks are heuristics: a deploy event can always be delayed in its own logging pipeline, an incident can always be misfiled, and any system has to pick an allowed-lateness threshold beyond which it stops waiting and accepts it may be wrong. Tightening that threshold catches more staleness at the cost of more false alarms; loosening it does the reverse. Someone — an SRE, a platform team, a policy — has to own that knob, and owning it is a judgement call, not an engineering solve.
What windowing buys is visibility into the cutoff itself. Instead of a dependency's reliability profile being silently frozen the day someone last checked it, it becomes a claim with a window attached: valid as of this join, subject to retraction on this evidence, decaying in confidence on this schedule. That is the entire difference between a system that can be caught trusting stale data and one that can be shown, on inspection, exactly when and why it stopped trusting something. In cloud infrastructure, where the dependency you called an hour ago is not guaranteed to be the dependency you're calling now, that difference is the whole of the job.