Skip to main content

Overview

The KaireonAI Domain Event Stream publishes lightweight notifications whenever the platform records an interaction or makes a recommendation. Subscribers (analytics workers, ML feature pipelines, external sinks) can consume these events without polling the OLTP database. This stream is separate from the POST /api/v1/events ingestion endpoint, which accepts inbound customer behavior events.

Topics

Event envelope

Every event is published as JSON with this shape:

Choosing a backend

The publisher backend is selected via the EVENT_PUBLISHER environment variable. Pick the trade-off that fits your operational story — durability, cost, ops weight all vary. Switch backends without code changes — set EVENT_PUBLISHER and the per-backend env vars below. Topic names + event payloads stay identical, so subscribers don’t need to be rewritten.

Local dev with Redpanda (free Kafka API)

Redpanda is a Kafka-compatible broker that runs as a single binary, no Zookeeper, no JVM. It is included as an optional Docker Compose profile:
For Redpanda Cloud Serverless (free tier survives indefinitely for low-traffic):

Durability — what each backend gives you

  • redis: none. Consumers must be online when an event fires. If no subscriber is connected to a topic, the event is silently dropped.
  • kafka / redpanda / msk: events are persisted to the broker. Consumers can replay from any offset within the configured retention window (default Kafka retention is 7 days). Multiple consumer groups read independently.
  • eventbridge: durable per-event delivery to subscribed targets. No replay (use SQS DLQ for failures).
  • kinesis: durable shards with 24-hour to 365-day replay window.
In all backends, the publish call is fail-open: if the broker is unreachable or required env vars are missing, the platform logs a warning and continues. The OLTP source of truth remains the interaction history table — query it directly if you need a replayable record older than your stream’s retention window.

Configuration reference

Common

Redis backend (EVENT_PUBLISHER=redis)

Kafka / Redpanda backend (EVENT_PUBLISHER=kafka or redpanda)

MSK backend (EVENT_PUBLISHER=msk)

(Equivalent env-var sets exist for eventbridge and kinesis — see the platform infrastructure container module for the full list.)

Sample subscriber (ioredis)

Where it’s wired

What happens when a publish fails

Every backend rejects on a failed publish — it logs the transport error and rethrows. Failure tolerance is the caller’s decision, not the transport’s, and the two callers make opposite choices:
  • Outbox events (outbox_events, drained by the outbox publisher) are the durable path. A rejection drives the retry/backoff ladder and, once maxRetries is exhausted, moves the event to dead_letter_events. Nothing is marked published unless the transport accepted it.
  • Stream events (interaction.recorded.v1, decision.made.v1) and the workers’ *.completed notifications are best-effort: they are emitted after the durable write has already committed, so a failure is logged and swallowed at the call site. Letting it propagate would fail a job that already succeeded and cause the work to be re-run.
Before 2026-08-15 every backend swallowed publish failures internally. The outbox therefore marked undelivered events published and dropped them, and its retry/DLQ branch was unreachable on all five backends. If you are running an older build, treat kaireon_outbox_processed_total{status="published"} from that period as “handed to the transport”, not “delivered”.
Rejection on publish is about handing the event to the broker. It is separate from durability once accepted: Redis pub/sub still retains nothing, so a consumer that is offline still misses events. See the backend table above.