Use Case · Integration

Event fanout on the Software Lifecycle Cloud

Event fanout on KERNSTACK starts where the change happens: a table declares a change stream that invokes a function with batched item changes, and that function routes the event to its subscribers — internal workers, outbound webhook delivery rows, workflow starts — as declared steps of the same project. One write, many consequences, and a record of each consequence beside the change that caused it.

The engineering bottleneck with assembled stacks

Teams call three webhooks from inside a request handler because it is the shortest path from “order created” to “everyone notified”. Then one subscriber hangs and the order request hangs; another fails silently and the warehouse never hears; and the handler grows into an accidental message bus with no retries, no record, and a deploy freeze whenever any subscriber misbehaves.

Architecture on the Software Lifecycle Cloud

The write stays a write. The table’s change stream delivers batched changes to a fanout function after the fact, which maps each change to its subscriber set — stored as data, so adding a subscriber is a row, not a release. Internal subscribers run as worker steps; external ones become delivery rows handled by the retry pattern. The handler that served the customer returns when the write lands; consequences proceed on their own clocks.

Subscribers as data

The subscriber registry being a table changes the politics of integration: a new consumer appears as a row with an owner and a destination, reviewable in a diff of data rather than a code change to a hot handler. Turning a misbehaving subscriber off is likewise a row update — the fanout survives its worst consumer by construction.

  • Change streams deliver after the stream is enabled and keep position across redeploys — no events lost to a deploy
  • Each subscriber’s delivery outcome is recorded per event, so “did the warehouse get it” is a lookup
  • Slow subscribers cannot slow the write path; they can only be late, visibly

Ordering, stated honestly

Fanout is at-least-once with per-subscriber outcomes, not a distributed transaction. Subscribers should be idempotent — most naturally by the event’s key — and the design says so in the open. Teams needing exactly-once theatre across systems are shopping for a different product and a longer invoice.

Frequently asked questions

Through the table’s declared change stream, which invokes a function with batched item changes written after the stream is enabled. Redeploying an unchanged stream keeps its position, so deploys do not skip or duplicate the feed.

Yes, if your registry is data: the fanout function reads subscriber rows per event. Adding a consumer is adding a row with its destination and owner — and removing one mid-incident is the same operation, reversed.

Its deliveries accumulate as rows with attempts and errors, then park when the budget ends. Other subscribers are unaffected, and when the endpoint returns, the parked deliveries replay from the record.

Related capabilities, architectures, and comparisons

Ship your stack on the Software Lifecycle Cloud.

Closed preview on dedicated European infrastructure. Bring a repository or start from a blueprint.