Kaiten
Architecture

Event Pipeline

Detailed flow from transactional outbox to webhook delivery.

Event Pipeline Architecture

End-to-End Flow

1. Go API Handler
   │  INSERT INTO outbox_events (same transaction as domain write)

2. PostgreSQL WAL
   │  Logical replication slot captures outbox_events INSERT

3. Debezium CDC Connector
   │  Reads WAL, transforms to CDC event envelope
   │  Publishes to RabbitMQ exchange: kaiten.events

4. RabbitMQ
   │  Fanout exchange → consumer queue

5. Dapr Sidecar (pubsub component)
   │  Subscribes to queue, HTTP POST to api endpoint

6. Go Webhooks Worker (/events endpoint)
   │  Parses Debezium CDC envelope
   │  Extracts: event_name, event_type, data, org_id
   │  Calls Svix API: svix.Message.Create()

7. Svix
   │  Routes to org's webhook endpoints by event type
   │  Retries with exponential backoff

8. Customer's Webhook Endpoints

outbox_events Table

CREATE TABLE outbox_events (
    id UUID PRIMARY KEY,
    event_name TEXT NOT NULL,      -- e.g. "CUSTOMER_CREATION"
    event_type TEXT NOT NULL,      -- e.g. "com.kaiten.customer.v1.created"
    payload JSONB NOT NULL,        -- domain data
    organization_id UUID NOT NULL,
    traceparent TEXT,              -- OpenTelemetry trace context
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

Debezium Configuration

Debezium is configured to watch the outbox_events table using the outbox event router SMT (Single Message Transform):

  • Source: PostgreSQL WAL logical replication
  • Table: public.outbox_events
  • Routing: event_type → RabbitMQ routing key

Svix Integration

Each Kaiten organization maps to a Svix Application. When an organization is created, a corresponding Svix app is created. Webhook endpoints and event types are managed through the Svix SDK.

Guarantees

  • At-least-once delivery: domain write + outbox insert are atomic
  • No message loss: Debezium reads from the PostgreSQL WAL
  • Ordered per table: events are processed in WAL insertion order
  • Idempotent processing: webhooks may be delivered more than once

On this page