Choosing the Right Transport Layer for Moleculer: NATS, MQTT, TCP, or Redis
Decide which Moleculer transport fits your latency, scalability, and fault‑tolerance needs. A concise comparison, trade‑offs, and a validation snippet help you pick the best option for your micro‑service architecture.
07 Aug 2026, 18:55 UTC

Problem Overview
When building a Moleculer micro‑service mesh, the transport layer you choose determines how services discover each other, how messages are routed, and what performance you can expect. Moleculer exposes a pluggable transport API, letting you swap between NATS, MQTT, TCP, or Redis. Each transport has its own strengths and constraints, and picking the wrong one can lead to sub‑optimal latency, limited scalability, or fragile fault tolerance.
Decision Context & Constraints
Before you dive into code, list the constraints that matter for your deployment:
- Latency & throughput – How fast must a request‑reply cycle complete?
- Message size – Do you send <1 KB payloads or larger blobs?
- Scalability – Do you need to scale to thousands of services or just a handful?
- Fault tolerance – Is high availability a must, or can you tolerate occasional outages?
- Deployment topology – Are services spread across data centers, edge devices, or a single cluster?
- Operational complexity – How much extra infrastructure can you manage?
Compact Comparison Table
| Transport | Latency (µs) | Throughput (req/s) | Scaling | Fault Tolerance | Message Size | Setup Complexity | Ideal Use Cases |
|---|---|---|---|---|---|---|---|
| NATS | ~10–30 | >50 000 | Clustered, horizontal | High – JetStream & clustering | Any, but <1 KB best | Broker cluster + config | High‑frequency APIs, event streams |
| MQTT | ~30–100 | ~10 000 | Broker‑centric, limited scaling | Basic – depends on broker | ≤256 KB per message (typical) | Broker + optional clustering | IoT, lightweight devices |
| TCP | ~5–15 | ~20 000 | Point‑to‑point, no auto‑scale | None – single point of failure | Any, but requires manual handling | Minimal – no broker needed | Simple, internal services, prototyping |
| Redis | ~15–40 | ~30 000 | Clustered, but limited pub/sub scaling | High with Redis Cluster | Large payloads ok (but memory bound) | Redis instance + cluster config | Cache‑heavy workloads, low‑latency messaging |
Trade‑Off Analysis
Latency & Throughput
TCP offers the lowest raw latency because it talks directly to the service’s port. However, Moleculer’s built‑in load balancing and service discovery are missing, so you must implement those yourself. NATS and Redis provide a good mix of low latency and high throughput, with NATS slightly ahead for bursty traffic.
Scalability
MQTT’s broker model is simple but scales poorly beyond a few thousand connections unless you add a clustering layer. Redis pub/sub is limited by the fact that each message is broadcast to all subscribers; scaling requires sharding or using Redis Streams. NATS is designed for horizontal scaling and can handle millions of connections with a cluster of brokers.
Fault Tolerance
Redis Cluster and NATS JetStream offer strong persistence and automatic failover. MQTT brokers often provide persistence but may require manual clustering. TCP offers no built‑in redundancy; a single broker failure kills the entire mesh.
Operational Complexity
If you already run a Redis cluster for caching, adding the Redis transport is almost zero friction. NATS requires a separate broker cluster, which adds operational overhead. MQTT needs a broker like Mosquitto or EMQX; scaling it often means adding a cluster manager.
Message Size Constraints
MQTT imposes a typical 256 KB limit per message, which can be a blocker for larger payloads. NATS and Redis have higher ceilings but still recommend keeping messages under a few megabytes to avoid memory pressure.
Concrete Implementation & Validation
Below is a minimal Moleculer service file that uses the NATS transport. Replace the placeholders with your broker details.
const { ServiceBroker } = require("moleculer");
const broker = new ServiceBroker({
nodeID: process.env.NODE_ID || "node-1",
transporter: {
type: "nats",
options: {
url: process.env.NATS_URL || "nats://localhost:4222",
// Optional: enable JetStream for persistence
// jetstream: true,
// Optional: connect to a cluster
// cluster: {
// name: "cluster-name",
// seed: "nats://seed-node:4223"
// }
}
},
logger: console,
logLevel: "info"
});
broker.createService({
name: "math",
actions: {
add({ a, b }) {
return a + b;
}
}
});
broker.start();
To validate the transport choice, run a simple benchmark:
- Deploy the service on two nodes (or Docker containers).
- Use
moleculer-benchor a custom script to send 1 KB payloads at 10 000 req/s to themath.addaction. - Measure round‑trip latency and throughput using
moleculer-bench --transport nats(replacenatswith the transport you are testing). - Check broker logs for dropped messages or reconnect events.
- Repeat the same test with a simulated network partition (e.g., using
tcto drop packets) to observe fault‑tolerance behavior.
After the benchmark, compare the metrics against the table above to confirm the chosen transport meets your SLA.
Limitations & Practical Checks
- All transports require a broker; missing connectivity will cause service discovery to fail.
- Message size limits are broker‑dependent; test with the largest payload you expect.
- For high‑availability, ensure your broker cluster is configured with persistence (e.g., NATS JetStream, Redis Cluster).
- Monitor broker metrics (latency, message backlog) continuously; Moleculer logs only the application layer.
Conclusion
Choose NATS when you need low latency, high throughput, and horizontal scaling in a production micro‑service mesh. MQTT is ideal for IoT scenarios with lightweight devices and modest scale. TCP is suitable for quick prototypes or internal services where operational overhead must be minimal. Redis offers a middle ground if you already run a Redis cluster and prefer a single‑tool stack. Validate each choice with a targeted benchmark that mirrors your real traffic patterns.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.