Skip to content

Narad vs. Everything Else

One comparison table teaches faster than a thousand docs pages. So here it is, written with a rule: when in doubt, the other system gets the benefit. Every one of these tools is excellent at what it was built for; the honest question is never "which is best" but "which was built for your problem." Where Narad loses, this page says so.

The matrix

Narad Kafka NATS JetStream RabbitMQ SQS Redis Streams Pulsar
Core model Queue-first on durable logs Partitioned ordered log Streams + consumers Broker with exchanges/queues Managed queue In-memory log + consumer groups Segmented log
Client protocol Plain HTTP: curl is a client Binary protocol, SDK required NATS protocol, SDK required AMQP, SDK required HTTP + SigV4 signing (SDK in practice) RESP, client library Binary protocol, SDK required
Per-message ack + visibility lease ✓ native ✗ (offsets only; build it yourself) ✓ (ack wait + redelivery) ✓ (the model Narad's leases resemble) ✓ (PEL + claim)
Delayed delivery ✓ native (delayed child topics) ✗ native (NAK-with-delay on redelivery only) Plugin or TTL+DLX tricks ✓ per-message, ≤15 min ✓ native, arbitrary
Fan-out (one msg → many independent streams) ✓ native child topics ✓ (consumer groups re-read the log) ✓ (multiple consumers per stream) ✓ (exchanges, its superpower) Needs SNS in front ✓ (multiple groups) ✓ (subscriptions)
Replay from offset ✓ native, non-destructive ✓ native ✓ native ✗ (gone is gone) ✓ (XRANGE) ✓ native
Ordering ✗, deliberately none ✓ per partition ✓ per stream ✓ per queue (mostly) FIFO queues only, throughput-capped ✓ per stream ✓ per partition
Replication Async opt-in per topic (fan-out replica) ✓ synchronous (ISR) ✓ Raft (R3/R5) ✓ quorum queues Managed, invisible Async (loss windows) ✓ BookKeeper quorums
Binary payloads over the wire API ✓ raw octet-stream ✓ (opaque bytes) ✗ text-only bodies, 1 MiB cap
Deployment footprint 1 binary, Raft inside Brokers + KRaft (historically ZooKeeper) 1 binary 1 broker (Erlang runtime) Zero: it's AWS's problem Your existing Redis Brokers + BookKeeper (+ZK/Oxia)
Runs on your laptop unchanged Heavier ✗ (emulators only) Painful
Stream processing ecosystem ✓✓ (Streams, Connect, ksql) Modest ✓ (Functions)
Maturity Weeks old: honest evidence, tiny track record Decades, battle-hardened everywhere Mature, CNCF Decades Fully managed since 2006 Mature Mature

Beyond features

Features tell you what a system does. The next four tables cover what it costs you to run one, what its promises actually mean, and how hard it is to leave. Same rule as above: when in doubt, the other system gets the benefit. All prices and citations are as of August 2026.

What an ack actually means (durability)

The most misunderstood dimension on this page. "Durable" hides three separate questions: is the message on disk when you get your ack, is it on more than one machine, and what faults can still lose it?

Ack means fsynced? Replication Acked-message loss windows
Narad ✓: group-commit fsync before the 202 ✗ single copy per partition; replica children are async, opt-in Losing a node's disk loses its partitions; plan volume snapshots or replica children
Kafka ✗ by default: flush to disk is effectively disabled (log.flush.interval.messages = Long.MAX); durability comes from replication RF=3 by convention, sync to the ISR with acks=all acks=1; ISR shrunk to 1 with min.insync.replicas=1; correlated power loss across replicas
NATS JetStream ✗ by default: file storage fsyncs on a 2-minute interval; sync_always exists but docs warn it drops to a few hundred msg/s R1 by default; R3/R5 is Raft, but the quorum ack is in-memory Jepsen (Dec 2025, v2.12.1) demonstrated acked-write loss even at R3/R5 under crash faults; R1 power loss can drop up to 2 min
RabbitMQ ✓ quorum queues fsync on a quorum before the confirm; ✗ streams don't fsync (OS writeback, like Kafka) 3 Raft members Quorum queues: majority disk loss only. Streams: correlated quorum power failure
SQS Stored redundantly across multiple AZs before the response (internals opaque, but that's the contract) Multi-AZ, managed None documented
Redis Streams ✗: default is RDB snapshots; AOF everysec still loses ~1 s; appendfsync always collapses to disk fsync rate None by default; replication is always async (WAIT is best-effort) Failover discards replication lag; the docs say so themselves
Pulsar ✓: BookKeeper fsyncs the journal on the ack quorum by default (standalone mode: no) E=2/W=2/A=2 defaults, synchronous Narrow: needs journalSyncData=false (a common perf tuning) or simultaneous loss of the ack quorum

Honest placement: Narad and Pulsar and RabbitMQ quorum queues are the only ones here that fsync before acking by default. Narad then concedes the other axis: it has no synchronous replication, so a dead disk is data loss where Kafka/JetStream-R3/quorum queues survive it. Different systems, different failure they're paranoid about. And Kafka, RabbitMQ, NATS, and Redis have all been through Jepsen; Narad's evidence is its own chaos matrix, self-administered, worth exactly that.

Messages per second on similar compute

Cross-system benchmarks are the least honest genre in infrastructure, so ground rules: every number below is from the linked source, with its hardware and durability config attached, because the fsync asymmetry above is the biggest confounder: Kafka's headline numbers don't fsync per message; Pulsar's do. Message sizes differ. Treat everything as order-of-magnitude.

System Published result Compute ≈ per broker vCPU Config during test
Kafka 605k msg/s @ 1 KB (2020) · ~1M msg/s @ 1 KiB (2023, independent re-run) 3 nodes, 24 / 72 vCPU ~14k–25k RF=3, acks=all, no fsync
Kafka, fsync per message 420k msg/s @ 1 KB (2020) 3 nodes, 24 vCPU ~17k RF=3, flush.messages=1
Pulsar 300k800k msg/s @ 1 KB (2020/2022, vendor) 3 nodes, 24 / 72 vCPU ~11k–13k RF=3 equivalent, journal fsync on
RabbitMQ quorum queues 66–67k msg/s @ 1 KB (2020, official) 72–112 vCPU clusters ~0.6k–0.9k RF=3, confirms, fsync
NATS JetStream 134k msg/s @ 128 B (file R1, real network; the official docs number, 404k, is loopback on a MacBook) 8 cores ~17k R1, async batch publish, lazy fsync. R3 costs ~40% more throughput
Redis Streams ~136k msg/s unpipelined · 0.5–1M pipelined (tiny payloads) 1 core (single-threaded) ~136k RDB only: the fastest number here carries the weakest durability
SQS Quota-bound, not compute-bound: standard is effectively unlimited in aggregate; FIFO is 3k msg/s batched by default, up to 700k in high-throughput mode in the biggest regions n/a (managed) n/a Multi-AZ, always
Narad 50k msg/s sustained, full produce → consume → ack 3 nodes × 4.5 vCPU ~3.7k (a floor, not a peak) fsync before ack, single copy, zstd

What the Narad row honestly is and isn't: the run ended because the load generator saturated, not the broker, so 50k is a floor, but it is our own bench, not an OpenMessaging run on standardized hardware, and we haven't measured the saturation point. Until an OMB-style run exists, the fair reading is: Narad sits in the "tens of thousands per node, fsync-durable" class with RabbitMQ quorum queues and JetStream, an order of magnitude below Kafka's log-append ceiling, which is fine, because we already told you to use Kafka if you need millions per second.

Same compute, measured ourselves

Published numbers come from different hardware, years, and vendors, so we also ran every system here (SQS can't be self-hosted) on identical resources: one broker at a time in Docker, 2 CPUs / 2 GB each, same driver, same workload (50k × 256 B; every produce waits for the system's per-message confirmation, then a full consume+ack drain; single node, no replication for anyone; each system in its default durable config). Laptop-grade and single-run (treat the ordering as directional), but it is the only table on this page where "similar compute" is literally true:

System Produce msg/s p50 / p99 Consume+ack msg/s What the produce ack means
NATS JetStream 39,525 0.4 / 0.8 ms 21,600 in the R1 file stream, fsync every 2 min
Redis Streams 31,643 0.5 / 0.8 ms 41,698 in the AOF buffer, fsync every 1 s
Kafka (6 partitions) 14,728 0.8 / 4.0 ms 7,830 page cache, no per-message fsync (default)
RabbitMQ (quorum queue) 13,014 1.2 / 1.9 ms 14,361 fsynced before the confirm
Pulsar (standalone) 7,632 2.0 / 3.0 ms 10,984 standalone disables the journal fsync
Narad 5,597 2.0 / 10.0 ms 8,567 fsynced (group commit) before the 202

The ordering is mostly the durability column priced in milliseconds: the systems that don't fsync per confirm top the produce chart; that's the trade, made visible. Within the fsync-per-confirm class, RabbitMQ's quorum queue outproduced Narad ~2.3× on this workload, and Narad's plain-HTTP consume pays two round trips per message where binary protocols pipeline: real costs of the curl-is-a-client design, stated rather than hidden. Zero produce failures and a full drain for every system.

What it costs to run

Two very different bills: machines (self-hosted) or usage (managed). Worked example for the managed column: a steady 100 msg/s × 1 KB ≈ 259M messages/month. Prices are us-east-1, August 2026; self-hosted figures are 3× m6i.large-class EC2 + disks and exclude ops labor, which is the real cost, and the reason "zero servers" is a feature.

Minimum HA self-hosted footprint ≈ $/month self-hosted Managed option, ≈ $/month at 100 msg/s
Narad 3 nodes, one binary each ~$220 ✗ none; you run it, that's the deal
Kafka 3 brokers (KRaft) ~$235–445 MSK ~$477 · Confluent Basic ~$30 (usage-priced)
NATS JetStream 3 nodes, one binary each ~$220 Synadia Cloud $49–199
RabbitMQ 3-node quorum cluster ~$220 Amazon MQ ~$651 · CloudAMQP HA ~$297
SQS ✗ can't self-host n/a ~$31 batched / ~$311 unbatched ($0.40/M requests × 3 calls per message)
Redis Streams primary + replica + sentinels ~$160 ElastiCache ~$218 · Redis Cloud from ~$25
Pulsar 3 brokers + 3 bookies + 3 metadata nodes per the official docs ~$725 StreamNative ~$75–110

The pattern: at low, steady volume the usage-priced managed services (SQS batched, Confluent Basic) are nearly free and unbeatable; self-hosting anything to save $30/month is bad math. Self-hosting wins when volume grows (SQS at 5,000 msg/s unbatched is ~$15k/month; a 3-node cluster is still ~$220), when payloads are binary, or when the queue can't leave your network. Narad's cost profile is the same as NATS's: the lightest self-hosted tier. Pulsar's floor is ~3× everyone else's: that's the platform-team tax in dollars.

Lock-in

License Protocol Who steers it Exit path
Narad Apache 2.0 Plain HTTP One young project; the bus factor is real and we won't pretend otherwise Replay any topic over HTTP into anything; no SDK to unwind
Kafka Apache 2.0 De-facto industry standard: Redpanda, WarpStream, AutoMQ and others reimplement it ASF The lowest lock-in of the log systems; your clients outlive your broker vendor
NATS JetStream Apache 2.0, CNCF NATS-specific Synadia, who moved to pull the server out of CNCF in 2025 before backing down. Resolved, but it happened Consumer-side migration; SDKs per language
RabbitMQ MPL 2.0 AMQP, an actual open standard Broadcom (via VMware) AMQP portability across brokers is real
SQS Proprietary AWS API + SigV4 AWS The deepest lock-in on this page; emulators cover local dev, not production
Redis Streams AGPLv3 (after the 2024 license exit and 2025 partial return) RESP, widely reimplemented Redis Ltd., with Valkey (BSD, Linux Foundation) as the fork insurance policy Valkey speaks the same protocol, Streams included
Pulsar Apache 2.0 Pulsar-specific (a Kafka-compat layer exists) ASF Fewest alternative implementations of the open-source options

Operating burden

The matrix's "deployment footprint" row, extended to day 2. Rough ranking, lightest first: SQS (there is no day 2; that's the product), then NATS and Narad (single static binary, flat config; Narad adds the operational surface described in Operate, and subtracts client SDKs; curl debugging is an underrated ops feature), then Redis (trivial until HA; then sentinels/cluster and the persistence asterisks), then RabbitMQ (decades of tooling and a good management UI, but Erlang tuning and cluster-partition lore come with it), then Kafka (KRaft killed ZooKeeper, but partition counts, consumer-group rebalancing, and JVM care remain a skill set), and finally Pulsar (three subsystems that each want understanding, the price of its feature list).

System by system

Kafka

Choose Kafka when you're event-streaming: high-fan-in pipelines, stream processing, the Connect ecosystem, strict per-partition ordering, or throughput in the millions of messages per second. Nothing here competes with that, including Narad.

Choose Narad when what you actually need is a job queue and you were about to deploy a log to get one. Kafka has no per-message acks, no visibility timeouts, no delayed delivery, no DLQ; you build all of it on top of consumer groups, and consumer-group rebalancing becomes your on-call's hobby. Narad starts from queue semantics and keeps the replayable log underneath.

NATS JetStream

The closest cousin on this page, and a system we genuinely admire: also a single binary, also Raft, also lease-style redelivery. The differences are philosophical: JetStream speaks the NATS protocol (SDK per language); Narad is HTTP-only, so your shell script, cron job, and Python service are equal citizens with zero dependencies. Narad adds native delayed topics (JetStream can delay a redelivery via NAK, but not a first delivery) and fan-out children that are full independent topics with their own retention. JetStream counters with synchronous replication and years of production maturity. If JetStream fits your brain and your team is happy vendoring SDKs, use it with our blessing.

RabbitMQ

Choose RabbitMQ when routing is your problem: topic exchanges, header matching, complex delivery topologies. That flexibility is real and Narad doesn't attempt it.

Choose Narad when you use RabbitMQ as "just a work queue" and the price (AMQP client libraries, Erlang runtime tuning, cluster partitions healing, a plugin for delayed messages) stopped feeling worth it.

SQS

The semantics twin: visibility timeouts, receipt handles, at-least-once: if you know SQS, Narad's consume model needs no explanation. Choose SQS when you're all-in on AWS and want zero servers; fully managed is a real feature.

Choose Narad when you want those semantics self-hosted: no cloud lock-in, no per-request bill at high volume, binary payloads (SQS bodies are text-only, 256 KB; every image or protobuf gets client-side base64), native fan-out without bolting SNS in front, and replay (SQS messages, once consumed, are simply gone).

Redis Streams

Choose Redis Streams when you already run Redis, your queue fits in RAM, and sub-millisecond latency matters more than durability guarantees. Choose Narad when the queue is the system of record: fsync-before-ack durability, disk-bounded retention instead of RAM-bounded, and a broker whose persistence story doesn't have an asterisk.

Pulsar

Feature-for-feature the richest system here: native delayed delivery, tiered storage, multi-tenancy. Choose Pulsar when you have a platform team to feed it: brokers plus BookKeeper plus coordination is the heaviest footprint on this page. Choose Narad when the feature list you actually need (queues, delay, fan-out, replay) fits in one binary a single engineer can operate and read.

What Narad concedes, in one place

So nobody has to hunt for it: no ordering guarantee (AP by design; if you need a sequence, carry one in the payload), no synchronous replication (single-owner partitions; the replica pattern is async and opt-in), no stream processing ecosystem, and no decade of production scars: the evidence is 300M+ soaked messages and a chaos matrix, which is a lot for week one and nothing next to Kafka's twenty years. If any single row above is your hard requirement, pick the tool that has it. If the shape of your problem is "durable work queue, plain HTTP, one binary, honest tradeoffs", that's the lane this whole system was built for.