Skip to main content

ADR-0002: Use NATS JetStream for Event Bus

  • Status: Accepted
  • Date: 2025-12-29
  • Deciders: @anshpansuriya14
  • Supersedes: N/A
  • Superseded by: N/A

Context

Framework M needs an event-driven architecture for:

  • Domain events (doc.created, doc.updated, doc.deleted)
  • Webhook triggers
  • Audit logging
  • Real-time notifications
  • Decoupled service communication

Forces at play:

  • Reliability: Events must not be lost
  • Replay Capability: New subscribers should access historical events
  • Pattern Matching: Subscribe to doc.* or todo.created
  • Consistency: Same infrastructure for jobs and events
  • Performance: High throughput, low latency

Decision

We will use NATS JetStream via nats-py for the event bus.

from nats.aio.client import Client

async def publish_event(nc: Client, topic: str, event: BaseEvent):
await nc.publish(topic, event.model_dump_json().encode())

async def subscribe_events(nc: Client, pattern: str, handler):
await nc.subscribe(pattern, cb=handler)

Consequences

Positive

  • Shared Infrastructure: Same NATS cluster for jobs (ADR-0001) and events
  • JetStream Durability: Messages persisted, consumers can replay from any point
  • Wildcard Subscriptions: doc.*, todo.> patterns for flexible routing
  • At-Least-Once: Acknowledgment-based delivery prevents message loss
  • Cross-Language: NATS has clients for Go, Rust, JS (future microservices)

Negative

  • Complexity: JetStream streams require configuration (retention, limits)
  • Ordering: Partitioned ordering (by key) not global order
  • Learning Curve: Different model than Redis Pub/Sub

Neutral

  • Messages use CloudEvents format for interoperability
  • Consumer groups supported via queue subscriptions

Alternatives Considered

OptionProsCons
Chosen: NATS JetStreamDurable, replay, shared with jobsLearning curve
Redis Pub/SubSimple, fastNo persistence, no replay
Redis StreamsPersistent, consumer groupsNo pattern matching, Redis-only
KafkaEnterprise-grade, provenHeavy, operational complexity
RabbitMQMature, flexible routingSeparate system from jobs

References