Webhooks for your database.
A row changes, an HTTP request fires. No trigger functions, no cron polling a updated_at column, no outbox table to drain.
The problem
Every product eventually needs to do something when data changes: notify a customer when an order ships, kick off a job when a document is uploaded, call a partner API when a record is approved. The usual answers — database triggers calling out, a poller on a timestamp column, an outbox table and a worker — each add code to maintain and a failure mode to debug.
How it works with Waltail
Waltail reads the write-ahead log through logical replication, so every committed change is captured without touching your schema. The webhook sink POSTs batches of changes to a URL you own, signed with HMAC-SHA256, retried with backoff, and in order per row. Your handler verifies the signature, reads op, table and data, and does the work.
For customer-facing webhooks — "notify my users when their rows change" — put a small service behind the sink that looks up the tenant from the row and forwards to their registered endpoint. Waltail handles capture, durability and retries; your service handles fan-out and tenant rules.
What to watch
- Make the handler idempotent on
idempotency_key; delivery is at-least-once. - If you need the previous values on update, set
REPLICA IDENTITY FULLon the table sooldis populated. - An endpoint that is down for more than about fifteen minutes parks its messages as undelivered; replay them from the console when it is back.
Sinks for this
Webhooks
Any HTTPS endpoint
Cloudflare Queues
Workers consumers
Amazon EventBridge
Rules, targets, event buses
Questions
Why not a database trigger?
Triggers run inside the transaction, so a slow or failing HTTP call slows or fails your write. Logical replication runs after commit, off the write path.
Why not an outbox table?
An outbox works, but you write and drain it yourself. With CDC, the tables you already have are the outbox.