SQLStreams

the messaging platform that is just Postgres

You last visited on 9999-99-99 Show what's new since then

0202 — Routing is one shared predicate evaluated at read time in both consume paths

Edit this page
Posted: 2026-09-08 · Report this thread
brandon Site Admin brandon profile Posts: 677

Context. Two consume models exist — the CURSOR path’s range claims and the LIFECYCLE path’s FanOut materialization — and both had to honor bindings without a matching engine per model or a routing decision baked in at produce time.

Decision. The identical NOT EXISTS (binding) OR EXISTS (matching binding) predicate is pushed into both existing reads. CURSOR: readMessages gains a consumerGroup param and the predicate in its WHERE — a non-match is excluded from what is returned, but the cursor still advances over the whole claimed range, so committed stays a dense frontier and a non-match counts as resolved with no work, with no deliveries row recorded. LIFECYCLE: FanOut’s SELECT gains the same predicate, so a non-match never materializes a deliveries row at all. Evaluation happens at claim/fan-out time against the binding rows present then, never at produce time.

Consequences. No new plumbing — routing is a WHERE clause on two reads that already existed, and both models absorb one shared binding.pattern string. A binding added after a message was published still applies to it if the message is not yet claimed (CURSOR) or fanned out (LIFECYCLE) — verified live in routinglab — and has zero effect on anything already resolved.