Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Tutorial: Fan-out Pattern

Deliver the same outbox events to multiple downstream systems simultaneously. Each system maintains its own consumer group with independent offset tracking.


The Pattern

                    ┌──▶ NATS (real-time notifications)
orders outbox ──▶──┼──▶ Kafka (analytics pipeline)
                    └──▶ Webhook (partner integration)

Each destination gets its own relay pipeline and consumer group, progressing independently.


Step 1: Create the Shared Outbox

SELECT tide.outbox_create('orders', p_retention_hours := 72);

Step 2: Create Consumer Groups

SELECT tide.create_consumer_group('nats-relay', 'orders');
SELECT tide.create_consumer_group('kafka-relay', 'orders');
SELECT tide.create_consumer_group('webhook-relay', 'orders');

Step 3: Configure Pipelines

-- To NATS
SELECT tide.relay_set_outbox('orders-nats', 'orders', 'nats',
  '{"url": "nats://nats:4222", "subject": "orders.events"}'::jsonb
);

-- To Kafka
SELECT tide.relay_set_outbox('orders-kafka', 'orders', 'kafka',
  '{"brokers": "kafka:9092", "topic": "orders"}'::jsonb
);

-- To partner webhook
SELECT tide.relay_set_outbox('orders-webhook', 'orders', 'webhook',
  '{"url": "https://partner.example.com/hooks/orders"}'::jsonb
);

Step 4: Monitor Independent Progress

SELECT * FROM tide.consumer_lag;
 group_name    | outbox_name | consumer_id | committed_offset | lag
---------------+-------------+-------------+------------------+-----
 nats-relay    | orders      | relay-0     |             1000 |   0
 kafka-relay   | orders      | relay-0     |              950 |  50
 webhook-relay | orders      | relay-0     |              800 | 200

The webhook relay is behind (maybe the partner endpoint is slow) — but it doesn't affect NATS or Kafka delivery.


Benefits

  • Independent progress — slow consumers don't block fast ones
  • Independent retry — if one sink fails, others continue
  • Single source of truth — all events come from the same outbox
  • No message duplication at the source — publish once, deliver many