centrifugo Documentation

Scalable real-time messaging server in a language-agnostic way. Self-hosted alternative to Pubnub, Pusher, Ably, socket.io, Phoenix.PubSub, SignalR.

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy centrifugo on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name centrifugo -p 8123:8123 --restart always zookeeper:latest
Configured Services & Ports
โš™๏ธ zookeeper
image: zookeeper:latest
โš™๏ธ clickhouse01
image: clickhouse/clickhouse-server:23-alpine
๐Ÿ”Œ Ports: 127.0.0.1:8123:8123, 127.0.0.1:9000:9000
โš™๏ธ clickhouse02
image: clickhouse/clickhouse-server:23-alpine
๐Ÿ”Œ Ports: 127.0.0.1:8124:8123, 127.0.0.1:9001:9000
โš™๏ธ clickhouse03
image: clickhouse/clickhouse-server:23-alpine
๐Ÿ”Œ Ports: 127.0.0.1:8125:8123, 127.0.0.1:9002:9000
โš™๏ธ clickhouse04
image: clickhouse/clickhouse-server:23-alpine
๐Ÿ”Œ Ports: 127.0.0.1:8126:8123, 127.0.0.1:9003:9000
docker-compose.yml
yaml (docker-compose.yml)
version: '3.8'
services:
  zookeeper:
    image: zookeeper:latest
    container_name: zookeeper
    hostname: zookeeper
    environment:
      ALLOW_ANONYMOUS_LOGIN: "yes"
    healthcheck:
      test: echo "ruok" | nc -w 2 localhost 2181
      interval: 5s
      timeout: 10s
      retries: 10
    volumes:
      - ${PWD}/zookeeper:/data
      - ${PWD}/zookeeper:/logs
  clickhouse01:
    image: clickhouse/clickhouse-server:23-alpine
    container_name: clickhouse01
    hostname: clickhouse01
    ports:
      - "127.0.0.1:8123:8123"
      - "127.0.0.1:9000:9000"
    volumes:
      - ${PWD}/clickhouse01:/etc/clickhouse-server
      - ${PWD}/clickhouse01_db:/var/lib/clickhouse
    depends_on:
      zookeeper:
        condition: service_healthy
  clickhouse02:
    image: clickhouse/clickhouse-server:23-alpine
    container_name: clickhouse02
    hostname: clickhouse02
    ports:
      - "127.0.0.1:8124:8123"
      - "127.0.0.1:9001:9000"
    volumes:
      - ${PWD}/clickhouse02:/etc/clickhouse-server
      - ${PWD}/clickhouse02_db:/var/lib/clickhouse
    depends_on:
      zookeeper:
        condition: service_healthy
  clickhouse03:
    image: clickhouse/clickhouse-server:23-alpine
    container_name: clickhouse03
    hostname: clickhouse03
    ports:
      - "127.0.0.1:8125:8123"
      - "127.0.0.1:9002:9000"
    volumes:
      - ${PWD}/clickhouse03:/etc/clickhouse-server
      - ${PWD}/clickhouse03_db:/var/lib/clickhouse
    depends_on:
      zookeeper:
        condition: service_healthy
  clickhouse04:
    image: clickhouse/clickhouse-server:23-alpine
    container_name: clickhouse04
    hostname: clickhouse04
    ports:
      - "127.0.0.1:8126:8123"
      - "127.0.0.1:9003:9000"
    volumes:
      - ${PWD}/clickhouse04:/etc/clickhouse-server
      - ${PWD}/clickhouse04_db:/var/lib/clickhouse
    depends_on:
      zookeeper:
        condition: service_healthy

File: README.md

Centrifugo

Scalable real-time messaging server in a language-agnostic way.






Centrifugo is an open-source scalable real-time messaging server. It instantly delivers messages to application online users connected over supported transports (WebSocket, HTTP-streaming, Server-Sent Events (aka EventSource), GRPC, WebTransport). Centrifugo has the concept of channel subscriptions โ€“ so it's a user-facing PUB/SUB server.

Centrifugo is language-agnostic and can be used to build chat apps, live comments, multiplayer games, real-time data visualizations, collaborative tools, AI streaming responses, etc. in combination with any backend. It is well suited for modern architectures and allows decoupling the business logic from the real-time transport layer.

The core idea of Centrifugo is simple โ€“ it's a PUB/SUB server on top of modern real-time transports:

Your backend communicates with Centrifugo over a simple HTTP or GRPC API to publish messages into channels, while clients subscribe to those channels using one of the official SDKs (or the unidirectional approach with no SDK dependency).

Quick start

Spin up Centrifugo with its embedded admin UI using Docker:

bash
docker run -it --rm -p 8000:8000 centrifugo/centrifugo:latest centrifugo \
  --client.insecure --admin.enabled --admin.insecure
# ^ insecure flags: for local trial only, never use in production

Then open http://localhost:8000 to reach the admin UI, where you can watch live connections and publish messages into channels. The insecure flags above remove authentication for a frictionless local trial only โ€“ never use them in production.

For native binaries, Homebrew, packages, and production configuration see the installation instructions, and follow the quickstart tutorial to connect your first client.

Why Centrifugo

The hard part is to make the PUB/SUB concept production-ready, efficient, flexible and available from different application environments. Centrifugo is a mature solution that already helped many projects with adding real-time features and scaling towards many concurrent connections. It provides a set of features not available in other open-source solutions in the area:

  • Efficient real-time transports: WebSocket, HTTP-streaming, Server-Sent Events, GRPC, WebTransport (experimental)
  • Built-in scalability with Redis (or Redis Cluster, or Redis-compatible storage โ€“ ex. AWS Elasticache, Valkey, KeyDB, DragonflyDB, etc), PostgreSQL or Nats.
  • Simple HTTP and GRPC server API to communicate with Centrifugo from the app backend
  • Asynchronous PostgreSQL and Kafka consumers to support transactional outbox and CDC patterns
  • Flexible connection authentication mechanisms: JWT and proxy-like (via request from Centrifugo to the backend)
  • Channel subscription multiplexing over a single connection
  • Rich subscription model: stream (client-side and server-side), map, shared poll, and proxy subscription streams
  • Various channel permission strategies, channel namespace concept
  • Hot message history in channels, with automatic message recovery upon reconnect, cache recovery mode (deliver latest publication immediately upon subscription)
  • Delta compression in channels based on Fossil algorithm
  • Online channel presence information, with join/leave notifications
  • A way to send RPC calls to the backend over the real-time connection
  • Strict and effective client protocol wrapped by several official SDKs
  • JSON and binary Protobuf message transfer, with optimized serialization and built-in batching
  • Beautiful embedded admin web UI
  • Great observability with lots of Prometheus metrics exposed and official Grafana dashboard
  • And much more, visit Centrifugo documentation site

Client SDKs

Official SDKs wrap Centrifugo's bidirectional protocol and handle reconnects, subscription state, message recovery, and more across platforms:

Platform / Language SDK
JavaScript (browser, Node.js, React Native) centrifuge-js
Dart / Flutter (mobile and web) centrifuge-dart
Swift / native iOS centrifuge-swift
Java (Android, JVM) centrifuge-java
Python (asyncio) centrifuge-python
Go centrifuge-go
.NET / MAUI / Unity [WIP] centrifuge-csharp

For simple use cases Centrifugo also supports a unidirectional approach (WebSocket, SSE, HTTP-streaming, GRPC) that needs no SDK โ€“ any standard client for the transport works. See the transports overview and the client protocol spec for details.

Documentation

Community

Found a bug or have an idea? Open an issue.
Want to contribute? See CONTRIBUTING.md.

Backing

This repository is hosted by packagecloud.io.

Also thanks to JetBrains for supporting OSS (most of the code here written in Goland):


File: internal/proxyproto/readme.md

Proxy transform rules:

Client protocol type Proxy type Headers Meta
HTTP HTTP In request headers No meta
GRPC GRPC No headers In request meta
HTTP GRPC In request meta No meta
GRPC HTTP No headers In request headers

File: internal/config/envconfig/README.md

envconfig

This is a fork of https://github.com/kelseyhightower/envconfig to make it fit Centrifugo, original license left unchanged.

There are changes to have access to VarInfo and to avoid using defaults for non-zero values.


File: misc/clickhouse_cluster/readme.md

Clickhouse Cluster

Clickhouse cluster with 2 shards and 2 replicas built with docker-compose.

Run

text
make config
docker compose up

Profiles

  • default - no password
  • admin - password 123

File: misc/benchmarking/k6/readme.md

A simple script which demonstrates benchmarking Centrifugo with k6. You can use it as a starting point.

It connects to Centrifugo with JWT per user, subscribes to the test channel, waits some time and exits.

Running test

Run Centrifugo with config like this:

json
{
  "token_hmac_secret_key": "secret",
  "admin": true,
  "admin_password": "password",
  "admin_secret": "0453661f-8b95-4f75-ab49-cfb2e3b2024f",
  "api_key": "7d8cee29-f5c0-419e-ae70-760767b21f8e",
  "allow_subscribe_for_client": true,
  "allowed_origins": []
}

Then:

text
k6 run benchmark.js

Make sure your system is tuned for dealing with many connections.


File: misc/redis_cluster/readme.md

Create local Redis cluster consisting of N nodes with M replicas each, ex:

text
bash create_cluster.sh 3 0

Cluster nodes will work until script interrupted. The goal of having this script is for development and benchmarking.

All data will be saved to local directory cluster_data. By default, Redis runs without RDB and AOF (--save "" --appendonly no).


File: misc/redis_instances/readme.md

Create local N isolated Redis master instances starting from port 6000:

text
bash start_instances.sh 3

Redis nodes will work until script interrupted. The goal of having this script is for development and benchmarking.

By default, Redis runs without RDB and AOF (--save "" --appendonly no).