Two systems in one name — fast fire-and-forget pub/sub, and a durable persistence layer on top — plus where each sits next to Kafka in this repo.
Your win: distinguish core NATS from JetStream, place NATS against Kafka in this
repo, and identify the pieces (golib, streams, subscribers) so every later lesson has a home.
What NATS is
NATS is a lightweight, very fast messaging system — a single Go binary that
moves messages in memory with sub-millisecond latency, built for microservice eventing.1
In this repo it's one of two event buses (Kafka is the other), and it comes in two flavours
that people constantly conflate:
⚡ Core NATS
Plain publish/subscribe, at-most-once. If no subscriber is
listening the instant a message is published, it's gone — no storage, no replay. Fast,
simple, fire-and-forget fan-out.
💾 JetStream
A persistence layer on top of core NATS. It captures messages into
streams and replays them to consumers — adding
at-least-once delivery, replay, and dedup. This course is JetStream.
The distinction that matters
Core NATS is at-most-once: a message with no listener vanishes. JetStream is
at-least-once: the server stores the message and keeps redelivering until
a consumer acknowledges it.2 Every durable event in this
repo — a user created, a notification requested — rides JetStream, precisely because it must not
be lost if the subscriber is momentarily down.
NATS vs Kafka — this repo runs both
You've done the Kafka course and the CDC course. So why also NATS? They divide the work:
NATS JetStream
Kafka
Feel
lightweight, ultra-low-latency, in-memory-fast
heavier, disk-durable, very high throughput
Used here for
internal service events & fan-out (user/staff/usergroup upserts, push-notification requests, the activity-log firehose)
durable pipelines: CDC, the outbox, email, bulk jobs, DWH sync
Subjects/topics
dotted PascalCase (Staff.Upserted)
{team}.{topic}
A live migration to know about
Some flows are moving from NATS to Kafka (gated by an Unleash flag). You'll find
NATS subscribers commented out with a note pointing to their Kafka replacement — and the same
business handler deliberately reused by both transports. So "which bus?" sometimes means "which
bus today." We'll cover the trade-off properly in Lesson 12.
The flow, and where the pieces live
publisher ──Subject.Name──▶ STREAM ──▶ CONSUMER ──▶ subscriber
(usermgmt) e.g. User.Created (durable store) (cursor) (conversationmgmt / notification)
the golib: internal/golibs/nats/jetstream.go ← the JetStreamManagement client (publish/subscribe)
streams: cmd/server/fink/streams/*.go ← provisioned by the "fink" job
names: internal/golibs/constants/common.go ← Subject*/Stream*/Queue*/Durable*/Deliver*
YOUR subs: internal/{conversationmgmt,notification}/.../nats/* ← the anchor
Four stops: a service publishes on a subject; JetStream captures
it in a stream; a consumer is your service's cursor into that stream; your
subscriber handles the message. Parts 1–3 walk this left to right, ending in your
own code.
Read this next
What JetStream is (and how it compares)
The clearest overview of core NATS vs JetStream, and where NATS fits against other systems.
A service publishes on a subject → JetStream captures it in a stream
→ a consumer is the cursor → your subscriber handles it.
Recall: core NATS vs JetStream, NATS vs Kafka, the flow.
two flavours + the split + the flow, then reveal
NATS = lightweight, in-memory-fast messaging (a single Go
binary). Core NATS = pub/sub, at-most-once (no listener → gone,
no persistence). JetStream = a persistence layer — captures into streams,
replays to consumers, at-least-once + replay + dedup (this course).
NATS vs Kafka (both run here): NATS = low-latency internal service events / fan-out
+ the activity-log firehose (dotted PascalCase subjects); Kafka = durable high-throughput pipelines
(CDC, outbox, DWH; {team}.{topic}). Active NATS→Kafka migration
(Unleash-flagged; commented-out subs). Flow: publisher → Subject.Name →
STREAM → CONSUMER → subscriber. Pieces: golib internal/golibs/nats; streams via
fink; names in constants/common.go; your subs in conversationmgmt/notification.
🎯 Interview one-liner
"You use NATS and Kafka — why both?" → "NATS JetStream for low-latency internal service
events and fan-out — user/staff upserts, notification requests, the audit-log firehose — where we
want simple, fast, at-least-once eventing. Kafka for durable, high-throughput pipelines like CDC and
the outbox. Core NATS is at-most-once; JetStream adds the persistence that makes it safe for events
that can't be lost."
Next lesson: the addressing scheme — subjects and pub/sub, wildcards, and the
queue groups that load-balance your subscribers. Unsure whether something is NATS or Kafka?
Ask me — that's what I'm here for.