Repository navigation
Choosing a backend
- You're picking between Redis and NATS for Scale out.
- You already use one of them and want to confirm it'll work.
- You want a starting point for your own benchmark.
Use Redis unless you have a specific reason not to.
If you already run Redis for caching or sessions, the operational delta is near zero. NATS is the better choice if you want a smaller dependency, are already running it for service-to-service messaging, or want simpler clustering.
Either backend will saturate a single neffos instance long before it becomes the bottleneck for most chat / notification / live-update workloads.
| Question | Redis | NATS |
|---|---|---|
| Already in our stack? | Often yes. | Less common. |
| Operational overhead | Familiar to most ops teams; single binary; rich tooling. | Tiny binary (<20MB), simpler config, but less institutional muscle memory. |
| Memory footprint at idle | ~few MB. Grows with key space. neffos uses none. | ~few MB. neffos uses none. |
| CPU at high pub/sub rate | Single-threaded pub/sub dispatcher; can become CPU-bound on large fan-outs. | Multi-threaded; tends to scale better with cores. |
| Clustering |
cluster mode (sharded keys); neffos uses Clusters []string config. |
Gossip-based; just point each neffos instance at any node. |
| Auth |
requirepass, ACLs, TLS. |
NKey, JWT, mTLS. |
| Persistence | RDB/AOF; neffos does not use it. | JetStream; neffos does not use it. |
| Cross-DC | Run a separate Redis per DC; bridge with a custom relay. | Built-in cluster gossip across DCs. |
| Local dev story |
docker run --rm -p 6379:6379 redis. |
docker run --rm -p 4222:4222 nats. |
Both backends use only the pub/sub primitive, not the persistence or queue features:
- Subscribe to a per-connection channel (for
To:-targeted messages). - Subscribe to a per-namespace channel.
- Publish a serialized neffos
Messageto the right channel. - Subscribe to a per-Ask channel for replies.
That means JetStream / RDB / cluster persistence are unused. Don't over-provision storage; do provision CPU and network for pub/sub fan-out.
import "github.com/kataras/neffos/stackexchange/redis"
exc, err := redis.NewStackExchange(redis.Config{
Network: "tcp",
Addr: "127.0.0.1:6379",
Password: "", // or os.Getenv("REDIS_PASSWORD")
DialTimeout: 5 * time.Second,
MaxActive: 10, // pool size
}, "my-app") // channel prefix, unique per neffos app
if err != nil { log.Fatal(err) }
server.UseStackExchange(exc)Cluster mode:
exc, err := redis.NewStackExchange(redis.Config{
Clusters: []string{"r1:6379", "r2:6379", "r3:6379"},
}, "my-app")Pick a unique channel prefix per neffos app. If two unrelated apps share one Redis with the same prefix, they'll receive each other's broadcasts.
The stack exchange package is also named nats, like the official client, so alias one of the two imports:
import (
natsexc "github.com/kataras/neffos/stackexchange/nats"
"github.com/nats-io/nats.go"
)
exc, err := natsexc.NewStackExchange("nats://localhost:4222")
if err != nil { log.Fatal(err) }
server.UseStackExchange(exc)With auth:
exc, err := natsexc.NewStackExchange("",
nats.UserInfo("user", "pass"),
// or nats.UserCredentials("/path/to/user.creds")
// or nats.Secure(tlsConfig)
)Set a unique subject prefix per neffos app:
exc.SubjectPrefix = "my-app.neffos"What happens during a broker outage?
| Scenario | Redis | NATS |
|---|---|---|
| Broker down at startup |
NewStackExchange returns error. |
Same. |
| Broker dies after startup | go-redis reconnects its pub/sub connections automatically; messages published during the outage are lost. | NATS client reconnects automatically; messages published during the outage are lost. |
| Slow broker | Publishes block briefly; can backpressure callers. | Same. |
| Network partition | Each instance still serves its local clients; cross-instance traffic is lost during the partition. | Same. |
Neither backend persists in-flight broadcasts in the default configuration. If you need durable broadcast (e.g. "every connected user must eventually see this notification"), persist it in your own store first and re-broadcast on reconnect.
Numbers vary wildly with message size and fan-out, but a few rules of thumb:
- A single Redis instance can push ~100K small pub/sub messages per second on commodity hardware.
- A single NATS server can push ~5–10x that for the same workload.
- The neffos in-process broadcaster (no StackExchange) is faster than either. Scale-out is a network round-trip you pay for cross-instance delivery.
If you're approaching broker throughput limits, first check whether you can shard by namespace (each namespace is a separate channel/subject) before changing brokers.
If neither backend fits (a different broker, an in-process bus for tests), implement the StackExchange interface yourself. See Writing a custom StackExchange.
- Scale out, overview and three-line setup
- Scale out using Redis, full Redis configuration
- Scale out using Nats, full NATS configuration
- Architecture, what neffos calls into the backend
Home | About | Project | Getting Started | Technical Docs | Copyright © 2019-2026 Gerasimos Maropoulos. Documentation terms of use.
Getting started
Concepts
Messaging
Production
Scale out