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.