
Beyond streaminglog processing
NATS JetStream and Apache Kafka — the architectural differences that matter, and where each one wins.
- Author
- Jean-Noël Moyne
- Compares
- NATS 2.12 / Apache Kafka 4.2
The Short Version
Executive Summary
NATS JetStream and Apache Kafka overlap in functionality but differ in architecture.
Apache Kafka is a distributed append-only log processing system designed for write throughput and at its core, log persistence and replay is its sole function. However, that core publish/consume functionality is limited which is why the Confluent Platform includes other components — each running as separate JVM processes — to offer a more complete set of functionalities. If you want to do things such as:
- Filtering of messages in topics
- Merging topics into other topics
- Use streams as Key/Value tables or as queues
Then you will have to also use Apache Kafka Streams, Flink, MirrorMaker and others. This means that you need to run many more JVMs than just the Kafka brokers (and Zookeepers if you don't use or haven't migrated to version 4), and that some of the data will be constantly shuffled back and forth between the Kafka broker and Kafka Streams JVMs and may end up being stored multiple times over multiple topics, affecting latency and efficiency, resource usage and, when using cloud services, can add noticeably to the costs (networking, storage).
NATS consolidates messaging, streaming, Key/Value, Object Store, queue semantics, service discovery, multi-region super-clustering, edge leaf nodes, MQTT, and WebSockets into a single binary with a single operational surface (less than 20MB binary) with zero dependencies. The practical consequences of this architectural difference show up across every dimension compared in this paper.
Kafka 4 has closed some historical gaps but the architectural differences, however, remain: Kafka's model is a partitioned append-only log extended by external components, while NATS JetStream is a consistent addressable message store with messaging, queuing, and data storage built in.
Neither system is universally better. Kafka's ecosystem depth, transactional model, and throughput optimizations make it the stronger choice for large-scale log processing with deep Flink/Iceberg/Schema Registry integration. NATS JetStream's unified architecture, operational simplicity, compliance-friendly deletion, multi-tenant security, and edge deployment capabilities make it the stronger choice for teams building modern distributed applications that span messaging, streaming, and data storage in a single platform.
The two are not mutually exclusive — they bridge cleanly via Synadia Connect, Debezium Server, or direct protocol adapters, and can coexist cooperatively in the same architecture.
The Bottom Line
Key Takeaways
This paper has argued that NATS with JetStream persistence is not merely a lighter-weight Kafka alternative but a fundamentally different architecture — one that collapses the distinction between messaging, streaming, queuing, and data storage into a single system with a single binary and a single operational surface. The differences that matter most fall into five categories.
Architecture: Kafka's model separates concerns across multiple process types: brokers, controllers, Connect workers, Schema Registry, stream processing runtimes (Kafka Streams, Flink), and replication tools (MirrorMaker, Cluster Linking). Each adds operational surface. NATS consolidates messaging, streaming, Key/Value, Object Store, queue semantics, multi-region topology (super-clusters), edge connectivity (leaf nodes), WebSockets, MQTT, service discovery, and stream mirroring into a single nats-server binary. Features are enabled in configuration, not by deploying new infrastructure.
Addressing and storage: Kafka stores data in partitioned, append-only topic logs addressed by offset. NATS JetStream stores data in streams that are addressed by hierarchical subjects with wildcards, support individual message deletion, can enforce per-subject constraints, and expose atomic compare-and-set write control. This makes JetStream simultaneously a stream, a key/value store, an object store, and a durable work queue — without external dependencies. It also makes targeted data deletion for GDPR and other compliance requirements a single API call rather than an architectural workaround.
Consumption: Kafka ties consumer parallelism to partition count and — even with share groups — retains partitions as a foundational abstraction. JetStream consumers are partition-less by default: scaling consumers up or down is a client-side operation with no server-side rebalance. For workloads that genuinely need subject-based partitioning, the Orbit client library extensions provide it as an opt-in layer, not a mandatory constraint.
Multi-tenancy, security, and deployment: NATS provides account-level multi-tenancy with isolated subject namespaces, delegated administration via JWTs and scoped signing keys, and a security callout mechanism for integrating with external identity providers. Deployment topologies span single clusters, super-clusters across regions and cloud providers, and leaf nodes at the edge with store-and-forward resilience during connectivity gaps. Kafka has no native equivalent to accounts, super-clusters, or leaf nodes.
Observability: NATS embeds monitoring into the server process: JSON telemetry endpoints, a push-based system account event channel, and — since 2.11 — built-in distributed message tracing with a single CLI command. Kafka's observability depends on JMX, external exporters, and client-side OpenTelemetry instrumentation, with no server-side message tracing capability.
Where Apache Kafka is stronger
Kafka is proven to work well for extremely high-throughput append-only workloads: batched ISR replication is optimized for maximum write throughput on large partitioned topics while JetStream's per-message Raft consensus provides stronger consistency guarantees but at a throughput cost that can matter at the highest end of the scale with small messages where you end up having to partition over multiple streams to scale the overall throughput.
Kafka's deep ecosystem and tight integration with Apache Flink, Iceberg, or the broader lakehouse ecosystem are strong points: the NATS ecosystem is growing — Synadia Connect, Debezium Server with the JetStream sink, Flink connectors — but it is smaller.
Where NATS JetStream is stronger
JetStream is the better fit — often decisively — for:
- Low latency: NATS has been designed for low latency over doing things like batching and compression for throughput, while it's the other way around for Kafka.
- Unified messaging and streaming: Workloads that need both low-latency request/reply and durable streaming in the same system, without operating two separate platforms.
- Multi-tenant SaaS platforms: Account-level isolation with delegated security administration, independent subject namespaces, and per-account resource limits — without manual topic namespace carving.
- Edge, IoT, and intermittent connectivity: Leaf nodes with local JetStream domains provide always-on messaging and store-and-forward durability even when disconnected from the hub, with automatic synchronization on reconnection. Native MQTT support eliminates the need for a protocol bridge.
- Compliance-sensitive workloads: Any pipeline carrying personal data that may be subject to erasure requests benefits from JetStream's per-message and per-subject deletion, secure overwrite, and audit trail capabilities.
- Operational simplicity: Teams that want a streaming platform they can deploy, operate, and monitor without JVM tuning, partition planning, multi-component coordination, or assembling an observability stack from parts.
- Global and multi-cloud deployments: Super-clusters with transparent cross-cluster routing, geo-affinity for request/reply, and built-in stream mirroring and sourcing — without MirrorMaker, Cluster Linking, or third-party replicators.
NATS and Kafka coexist well. Synadia Connect can bridge the two, consuming from Kafka topics and producing to JetStream streams (or vice versa) with transformation and filtering in the pipeline. Debezium Server can feed CDC events from the same databases into both systems independently. Organizations migrating incrementally can run both side by side, moving workloads as confidence grows, without a hard cutover.
The question is not which system is universally better — it is which architecture fits the workload better. For distributed log processing at massive scale with a deep surrounding ecosystem, Kafka is proven. For a unified messaging, streaming, and data store platform that is simpler to deploy, operate, and extend to the edge, NATS JetStream offers capabilities that Kafka's architecture cannot replicate without significant additional infrastructure.
The Full Paper
What's covered in detail
The complete paper goes deep on every topic below — architecture, semantics, operations, and the practical consequences of each design choice. If something looks relevant, the full PDF has the detailed treatment.
Introduction
- Executive Summary
Components
- Runtime and footprint
- Processes
- A note on the broader ecosystem
Functionality
- “Messaging” vs “Streaming”
- Messages
- “Subjects” vs “Topics”
- Streaming functionality
- Qualities of Service
- Data Store: JetStream persistence enables more than just Streams
- Queuing
- Cross-cluster behavior
- Microservices vs CQRS
- Durability
Protocol
Security
- Authentication
- Multi-tenancy
- Encryption
- Message deletion, data compliance, and GDPR
- Layer 7 Firewalling
Deployment and operations
- Resilience
- Clustering
- Super-clusters and Leaf Nodes
- Data placement
Operations
- Container orchestration
- Observability and monitoring
- Distributed message tracing
Administration
- Admin UI
Change data capture
- What NATS adds to CDC
- Other CDC tools
Stream Processing and Platform
- The Kafka-side compute layer has three tiers
- The NATS-side compute layer is thinner by design
- Direct client implementation
- Synadia Platform
- Flink with NATS
- KStreams and KTables compared to JetStream primitives
Summary
- They are not mutually exclusive
- Learn more

Free Download
Get the full white paper
This page is the summary. The complete white paper goes deep on every comparison — architecture, semantics, security, operations, and more. Enter your work email and we'll send you the PDF.
Frequently Asked Questions
How is NATS JetStream different from Apache Kafka architecturally?
Apache Kafka is a partitioned, append-only log optimized for write throughput. NATS JetStream is a consistent, addressable message store with subject-based routing, built-in queuing, Key/Value, and Object Store. Kafka relies on offset-based addressing within partitions, while JetStream uses hierarchical subjects with wildcard matching.
Did Kafka 4 close the gap by removing ZooKeeper?
Kafka 4.0 (March 2025) removed ZooKeeper and made KRaft the only metadata-management mode, which is a meaningful operational simplification. But a production Kafka deployment is rarely just brokers — Kafka Streams, Kafka Connect, Schema Registry, Flink, and MirrorMaker 2 are still separate JVM processes. NATS consolidates the equivalent capabilities into a single nats-server binary.
What does "subjects vs topics" mean in practice?
A NATS subject is a dot-separated hierarchical name like orders.region.us that supports wildcard matching (* matches one token, > matches one or more). Subscribers express interest by subject pattern. A Kafka topic has no hierarchy or broker-side wildcard subscription — filtering or content-based routing must use multiple topics or consumer-side filters.
How does NATS handle multi-region deployments compared to Kafka?
NATS supports super-clusters (clusters connected via gateways) and leaf nodes (lightweight edge connections) natively. Messages route across cluster boundaries based on subject interest, and stream mirroring or sourcing handles async replication. Kafka multi-region typically uses MirrorMaker 2 or Confluent's commercial Cluster Linking, both requiring additional configuration and processes.
Can NATS JetStream delete individual messages for GDPR?
Yes. JetStream supports direct message deletion by sequence number or stream purge with a subject filter — critical for GDPR. Kafka is an append-only log: the only options are retention expiry, log compaction with tombstones, or recreating topics. GDPR compliance in Kafka typically requires crypto-shredding (encrypting with per-user keys and deleting the keys).
What does NATS multi-tenancy look like compared to Kafka ACLs?
NATS has native multi-tenancy through accounts — each account is an isolated namespace with its own subjects, streams, and KV buckets, with per-account resource limits and selective subject exports. Kafka multi-tenancy is typically achieved through topic naming conventions and ACLs — there is no native account isolation in the open-source broker.
Do I have to choose between NATS and Kafka?
No. The two are not mutually exclusive — they bridge cleanly via Synadia Connect, Debezium Server, or direct protocol adapters. Many organizations run both: Kafka for batch analytics and data-lake integration, NATS for operational messaging, microservices, and edge deployments.
When does Kafka still win?
Kafka's ecosystem depth, transactional model, and throughput optimizations make it the stronger choice for large-scale log processing with deep Flink, Iceberg, or Schema Registry integration. If your workload is primarily batch or micro-batch ETL with established Kafka tooling, Kafka is the practical default.
When is NATS JetStream the better fit?
NATS JetStream's unified architecture, operational simplicity, compliance-friendly deletion, multi-tenant security, microsecond latency, and edge deployment capabilities make it the stronger choice for teams building modern distributed applications that span messaging, streaming, and data storage in a single platform — especially for real-time, multi-region, or edge-heavy workloads.