Introduction
Centrifugo is a standalone real-time messaging server that sits between your backend and your frontend clients. Your backend publishes messages via HTTP/gRPC API, and Centrifugo instantly delivers them to connected clients over WebSocket, SSE, or HTTP streaming. It is a self-hosted alternative to Pusher, Ably, and PubNub.
With over 10,000 GitHub stars, Centrifugo is used when you need real-time features (live chat, notifications, dashboards, collaborative editing, live feeds) without coupling your backend to WebSocket connections.
What Centrifugo Does
Centrifugo manages persistent connections from clients (thousands to millions) and delivers messages in real-time. Your application backend publishes messages to Centrifugo via API, and Centrifugo handles the fan-out to all subscribed clients. This decouples real-time delivery from your application logic.
Architecture Overview
[Frontend Clients]
Browser, Mobile, IoT
WebSocket, SSE, HTTP-streaming
|
[Centrifugo Server]
Connection management
Channel subscriptions
Presence tracking
|
+-------+-------+
| |
[Client API] [Server API]
Subscribe, Publish,
Publish, Broadcast,
Presence, Disconnect,
History Unsubscribe
|
[Scaling Layer]
Redis, KeyDB, NATS,
or Tarantool for
multi-node clusters
|
[Your Backend]
Django, Rails, Express,
FastAPI, Go, any languageSelf-Hosting & Configuration
// config.json
{
"token_hmac_secret_key": "your-secret-key",
"api_key": "your-api-key",
"allowed_origins": ["http://localhost:3000"],
"namespaces": [
{
"name": "chat",
"history_size": 100,
"history_ttl": "300s",
"presence": true
},
{
"name": "notifications",
"history_size": 50,
"history_ttl": "3600s"
}
]
}# Backend: publish message via API
import requests
requests.post("http://localhost:8000/api/publish", json={
"channel": "chat:room-42",
"data": {
"user": "Alice",
"text": "Hello everyone!",
"timestamp": 1700000000
}
}, headers={"Authorization": "apikey your-api-key"})// Frontend: subscribe to channel
import { Centrifuge } from "centrifuge";
const client = new Centrifuge("ws://localhost:8000/connection/websocket", {
token: "user-jwt-token"
});
const sub = client.newSubscription("chat:room-42");
sub.on("publication", (ctx) => {
console.log("New message:", ctx.data);
});
sub.subscribe();
client.connect();Key Features
- Language Agnostic — backend publishes via HTTP/gRPC, any language works
- WebSocket + SSE — multiple transport options for clients
- Channel System — organize messages by channels with namespaces
- Presence — track who is online in each channel
- History — message history and cache for late joiners
- Horizontal Scaling — scale with Redis, NATS, or Tarantool
- JWT Authentication — secure connections with JWT tokens
- Bidirectional — clients can publish and subscribe (configurable)
Comparison with Similar Tools
| Feature | Centrifugo | Socket.IO | Pusher | Ably | Mercure |
|---|---|---|---|---|---|
| Type | Standalone server | Library (Node.js) | SaaS | SaaS | Standalone server |
| Language | Go (any backend) | Node.js | Any (API) | Any (API) | Any |
| Self-Hosted | Yes | Yes | No | No | Yes |
| Scaling | Redis/NATS | Redis adapter | Managed | Managed | Mercure Hub |
| Presence | Yes | Yes | Yes | Yes | No |
| History | Yes | No | No | Yes | No |
| Cost | Free (OSS) | Free (OSS) | Per-message | Per-message | Free (OSS) |
| Best For | Self-hosted real-time | Node.js apps | Quick integration | Enterprise | SSE-based |
FAQ
Q: Centrifugo vs Socket.IO — which should I choose? A: Socket.IO if your backend is Node.js and you want tight integration. Centrifugo if your backend is any other language (Python, Go, Ruby, PHP) or you want a standalone, scalable real-time server.
Q: How many connections can Centrifugo handle? A: A single Centrifugo instance handles 100K+ connections. With Redis or NATS for scaling, a cluster handles millions. Performance depends on message rate and hardware.
Q: Do I need Redis for Centrifugo? A: No for single-node deployments. Redis (or NATS) is needed when you run multiple Centrifugo nodes to synchronize state and route messages between them.
Q: How does authentication work? A: Your backend generates a JWT token for each user. The client sends this token when connecting. Centrifugo validates the JWT and grants access to authorized channels.
Sources
- GitHub: https://github.com/centrifugal/centrifugo
- Documentation: https://centrifugal.dev
- Created by Alexander Emelin
- License: MIT