NATS is a lightweight, extremely fast messaging system — well suited for simple pub/sub patterns and microservices communication where RabbitMQ's additional features would be unnecessary overhead.
NATS vs RabbitMQ
| Factor | NATS | RabbitMQ |
|---|---|---|
| Resource footprint | Very lightweight (single small binary) | Heavier (Erlang runtime) |
| Throughput | Very high | High, but generally lower than NATS |
| Message persistence | Optional (via JetStream) | Built-in, more mature |
| Complexity | Simpler to run and reason about | More features, more complexity |
Prerequisites
- Ubuntu 22.04/24.04 or Debian 11/12 VPS
- Root or sudo access
Step 1 — Install NATS Server
curl -sf https://binaries.nats.dev/nats-io/nats-server/v2@latest | sh
sudo mv nats-server /usr/local/bin/
Step 2 — Create a Configuration File
sudo nano /etc/nats/nats-server.conf
port: 4222
http_port: 8222
authorization {
user: myapp
password: CHANGE_ME_STRONG_PASSWORD
}
jetstream {
store_dir: "/var/lib/nats/jetstream"
}
Step 3 — Create a systemd Service
sudo nano /etc/systemd/system/nats.service
[Unit]
Description=NATS Server
After=network.target
[Service]
ExecStart=/usr/local/bin/nats-server -c /etc/nats/nats-server.conf
Restart=always
User=nats
[Install]
WantedBy=multi-user.target
sudo useradd -r -s /bin/false nats
sudo mkdir -p /var/lib/nats/jetstream
sudo chown -R nats:nats /var/lib/nats
sudo systemctl daemon-reload
sudo systemctl enable --now nats
Step 4 — Allow the Required Port
sudo ufw allow 4222/tcp
Step 5 — Install the NATS CLI (Optional, for Testing)
curl -sf https://binaries.nats.dev/nats-io/natscli/nats@latest | sh
sudo mv nats /usr/local/bin/
Basic Pub/Sub Example (Node.js)
const { connect } = require('nats');
const nc = await connect({
servers: 'nats://YOUR_SERVER_IP:4222',
user: 'myapp',
pass: 'CHANGE_ME_STRONG_PASSWORD',
});
// Subscriber
const sub = nc.subscribe('orders.created');
for await (const msg of sub) {
console.log('Received:', msg.data.toString());
}
// Publisher
nc.publish('orders.created', Buffer.from(JSON.stringify({ orderId: 123 })));
Using JetStream for Persistent Messaging
Basic NATS pub/sub is fire-and-forget (subscribers must be connected to receive a message). For guaranteed delivery and persistence, enable JetStream (already configured above):
const js = nc.jetstream();
const jsm = await nc.jetstreamManager();
await jsm.streams.add({ name: 'ORDERS', subjects: ['orders.*'] });
Monitoring NATS
curl http://localhost:8222/varz
The built-in HTTP monitoring endpoint exposes server statistics — restrict access to this port at the firewall level, same as any monitoring endpoint.
Common Errors
Connection refused — verify the firewall allows port 4222 from your application's IP.
Messages lost when subscriber wasn't connected — expected behavior for basic pub/sub without JetStream; use JetStream if delivery guarantees matter for your use case.
Best Practices
- Enable authentication — never run NATS without it in production
- Use JetStream when message durability matters
- Restrict the monitoring HTTP port to trusted access only
Continue Reading
- Message Queue Basics: When and Why to Use One
- How to Install and Configure RabbitMQ on a VPS
- How to Monitor Message Queue Health and Performance
Browse more articles in Object Storage, Messaging & APIs.
