Files
nimmerworld.eachpath.local/learning/Publish-Subscribe.md
T

4.4 KiB

Publish-Subscribe

Everything in NATS starts with publish-subscribe. A publisher sends a message to a subject, and every subscriber listening on that subject gets a copy. This is the foundation everything else builds on.

How It Works

1.Publishers send messages to a subject — a simple string like orders.created
2.Subscribers express interest in subjects they care about
3.NATS delivers a copy of each message to every matching subscriber
4.No coupling — publishers don't know about subscribers, and subscribers don't know about publishers

This decoupling gives you tremendous flexibility. Services can be added, removed, or restarted without coordinating with anyone else.

Publishing Messages

You publish a message by sending it to a subject:

#!/bin/bash

Publish a message to the "weather.updates" subject

nats pub weather.updates "Temperature: 72°F"

Python:

Publish a message to the subject "weather.updates"

await nc.publish("weather.updates", "Temperature: 72°F".encode())

Key points:

1.Publishers don't wait for acknowledgments (fire-and-forget)
2.Messages are delivered to all active subscribers
3.If no subscribers exist, the message is simply discarded

Subscribing to Subjects

Subscribers express interest in subjects to receive messages:

#!/bin/bash

Subscribe to messages on the "weather.updates" subject

nats sub "weather.updates"

Python:

Subscribe to 'weather.updates' synchronously

sub = await nc.subscribe("weather.updates")

Process messages

while True: try: msg = await sub.next(timeout=1) print(f"Received: {msg.data.decode()}") except TimeoutError: break

When to Use Pub/Sub

Publish-subscribe is ideal when multiple services need to react to the same event:

1.Event broadcasting — notify services about user signups, order placements, deployments
2.Data distribution — send updates to multiple dashboards or monitoring services
3.Fan-out notifications — alert all interested parties about state changes
4.Audit logging — multiple services independently log the same events

Real-world example

Imagine an e-commerce system where an order is placed. You publish a single event:

nats pub orders.created '{"orderId": "123", "total": 99.99}'

Multiple services subscribe and each reacts differently:

1.Inventory Service updates stock levels
2.Email Service sends a confirmation email
3.Analytics Service records metrics
4.Shipping Service prepares the shipment

One publish, four independent reactions — no coordination needed.


The goldfish boundary (what this paper describes, precisely)

Everything above is core NATS: fire-and-forget, delivered to active subscribers only, discarded if no one listens. No memory. We found this the live way on 2026-11-06: nats sub "dev.>" caught dev.test.hello while the terminal sat open, and the bus has no record of it since.

JetStream adds the memory: streams claim subjects, messages are stored, durable consumers replay and each tracks its own position.

Estate mapping (our reality, host-verified)

Item Value Truth of record
Bus nats-dev.eachpath.local:30000 (VM 122) host record
Streams REGISTER -> nimmerverse.register.> (durable), CYCLE -> nimmerverse.cycle.> (100k msgs) host record, 2026-11-06
Publisher hosts aynee (nats-cli + nats-py 2.16.0 in nimmer-lib venv), nimmerworld-dev both, 2026-11-06
Core-mode example dev.test.hello = "Hello Nimmerverse!": live delivery only, in NO stream verified 2026-11-06

Note: the generic example orders.created has no stream here; on OUR estate, subjects without a stream are transient by design. Our persistent naming is nimmerverse.* under the two streams above.

Drills (run on our estate, record answers in section 5 of the 101 paper)

  1. Terminal A (nimmerworld-dev): nats pub nimmerverse.cycle.hello "dafit was here" Terminal B (aynee): nats sub "nimmerverse.cycle.*" - watch the * match exactly one token.
  2. nats stream info CYCLE - the bus has now counted the message.
  3. Kill both terminals, start a subscriber again: core-mode subject is empty, stream subject replays its history. That contrast IS the lesson.

Understand-check (ten words, said back before any primitive builds on this)

dafit's version: (to be said back)