NATS answers a different question than Kafka: not "how do I store and replay the firehose" but "how do all my services and devices talk, right now, with the least machinery possible." It is a single small Go binary (Apache-2.0, CNCF — confirmed staying so after the 2025 Synadia/CNCF settlement) that does connective messaging extremely well, with JetStream adding persistence when you need it.
Core NATS is subject-based pub/sub with at-most-once delivery: subjects are hierarchical (sensors.eu.berlin.temp), wildcards subscribe to patterns (sensors.*.*.temp, sensors.>), and three primitives cover most service communication:
The operational profile is the point: a ~20 MB binary, millions of messages/second on modest hardware, millions of cheap subjects (vs Kafka's comparatively heavyweight topics/partitions), clustering plus leafnodes and superclusters that span cloud-to-edge — the reason NATS owns the IoT/edge and service-mesh-adjacent niche.
JetStream (built into the same binary) adds Raft-replicated streams that capture subjects durably, with limits by age/size/count, and consumers — server-side views over a stream:
Wins: microservice connective tissue (request-reply + fan-out + queue groups in one hop), IoT/edge topologies (leafnodes tolerate flaky links; tiny footprint runs on gateways), control planes and command distribution, and platforms that want one small thing providing messaging + KV + occasional persistence. The simplicity dividend is real: NATS deployments tend to be set-and-forget.
Doesn't: the analytical streaming backbone. JetStream persistence is capable but not the point — the connector ecosystem, stream-processing integrations (Flink et al.), schema tooling, and multi-terabyte retention track record all live on the Kafka side. High-throughput data pipelines feeding warehouses and lakes remain log-platform territory; the common architecture uses both — NATS as the operational nervous system, Kafka-class logs at the analytical edge, bridged where they meet.