Services that react to data.
Every committed change becomes a message on the bus you already run, keyed by row. Services subscribe instead of calling each other.
The problem
The first service owns the orders table. The second needs to know when an order ships. The third bills when it is delivered. Wiring them with synchronous calls couples deploys and failure modes; writing events by hand next to every database write is the dual-write problem in a new costume.
How it works with Waltail
Capture the tables that matter and deliver to a queue or stream: Kafka with the row key as record key, SQS FIFO with message groups, Pub/Sub with ordering keys, NATS, RabbitMQ or EventBridge rules. The database becomes the source of truth for events; nothing is emitted that was not committed, and nothing committed is missed.
What to watch
- Consumers are at-least-once: dedupe on
idempotency_key. - Ordering is per row, not per table. If you need cross-row order, use
seqandcommit_lsnto sequence. - Design tables with the consumer in mind; the row is the event.
Sinks for this
Apache Kafka
Any Kafka-protocol broker
Amazon SQS
Standard and FIFO queues
Google Pub/Sub
Native ordering keys
NATS JetStream
Nats-Msg-Id dedupe
RabbitMQ
Exchanges, confirms
Amazon EventBridge
Rules, targets, event buses
Questions
Is this the transactional outbox pattern?
It is the same guarantee without the outbox table: CDC reads committed changes from the log, so the event and the write cannot disagree.