github centrifugal/centrifugo v6.8.0

4 hours ago

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

For details, go to the Centrifugo documentation site.

What's changed

This release introduces two new subscription primitives and three Postgres-backed components. Centrifugo evolves from a channel-based pub/sub server into a real-time companion for Postgres-backed applications. From a stream based broker to a state synchronization realtime backend.

A blog series accompanies this release. Two posts are published today:

Five more posts will follow during this week, covering map subscriptions, the PostgreSQL stream broker, the PostgreSQL controller, and a wrap-up tying it all together:

  • Day 2: Map subscriptions (Part 1) — synchronized key-value state and presence
  • Day 3: Map subscriptions (Part 2) — when your PostgreSQL transaction is your real-time publish
  • Day 4: Transactional publishing for stream subscriptions with PostgreSQL
  • Day 5: Multi-node Centrifugo on PostgreSQL alone
  • Day 6: Wrap-up: Beyond PUB/SUB: new foundations, and a real-time companion for PostgreSQL

Note, we consider map subscriptions and shared poll experimental for now. Features are huge and we expect API to stabilize within next months.

Highlights of release

  • Map subscriptions — new subscription type for synchronized key-value collections (cursors, presence, scoreboards, dashboards, feature flags).
  • Shared poll subscriptions — new subscription type for read-only state where the backend doesn't control writes (third-party feeds, configuration sync, live counters).
  • PostgreSQL stream broker — transactional publishing for stream subscriptions inside your SQL transactions.
  • PostgreSQL map broker — transactional publishing for map subscriptions inside your SQL transactions.
  • PostgreSQL controller — multi-node Centrifugo clusters on PostgreSQL alone, no Redis required.

Yes, Centrifugo multi-node cluster only on PostgreSQL is now possible.

Map subscriptions

A new subscription type that delivers synchronized key-value collections over the same WebSocket connection. Centrifugo keeps the collection in the map broker; the client stays in sync.

Three modes for different state shape:

  • ephemeral — usually memory or Redis backed, no recovery on reconnect (cursors, typing indicators, in-flight game state).
  • recoverable — time-bounded recovery from stream within a window, state converges with the help of offset/epoch mechanics.
  • persistent — durable, no per-key TTL — entries live until explicitly removed (feature flags, configuration, catalog state).

Key features:

  • Three-phase sync protocol resolves the race between paginated initial state and concurrent updates.
  • Per-key TTL handles cleanup on disconnect.
  • CAS-style conditional writes handle concurrent updates safely.
  • Convergence on reconnect guaranteed by offset/epoch tracking (in recoverable and persistent modes).

Docs: Map subscriptions
Demos: v6/map_demo collection — cursors, polls, sprint board, scoreboard, inventory, lobby, tickers, sync protocol visualizer.

Map presence

Map subscriptions introduce a new presence model built on the same sync protocol. Two server-managed subscription types replace the polling-style traditional presence API for use cases that need it:

  • map_clients — one entry per connection (client presence).
  • map_users — one entry per user (user presence).

Enabled via map_clients_presence_channel_prefix and map_users_presence_channel_prefix on the parent namespace. Presence is published to a separate channel (prefix + channel), so subscribers opt in independently of the parent subscription. Works alongside any parent subscription type (stream, map, shared_poll).

Advantages over traditional presence:

  • Paginated state delivery for large participant lists.
  • Stream-based catch-up on reconnect (with recoverable mode) — clients receive only the join/leave changes they missed, no full re-fetch.
  • Out of the box convergence (must be in recoverable mode for convergence property)

Docs: Presence channels
Demo: v6/map_presence_demo — 100k and 1M presence members synchronized to a single browser tab

Shared poll subscriptions

Server-side polling inversion for read-only state where the backend doesn't control writes. Instead of N clients each polling the backend, Centrifugo aggregates interest across all clients on a node and polls the backend once per cycle for the union of tracked keys. Backend load scales with O(unique items tracked), not O(connected clients).

Key features:

  • Per-key authorization via HMAC signatures (faster than JWT, first-class values in protocol).
  • Direct publish via shared_poll_publish lowers latency on application write paths.
  • Versionless and versioned modes for flexible backend integration.
  • Cold-key auto-poll: when a new client tracks a key with no cached data, Centrifugo triggers an immediate backend poll without waiting for the next cycle.
  • Reconnect resilience with version comparison: clients reconnect, replay tracked keys, only changed data re-delivered.

Docs: Shared poll
Blog: Shared poll subscriptions: O(unique items) polling with low-latency updates
Demos: v6/shared_poll_demo — votes, drones

PostgreSQL stream broker

Transactional publishing for stream subscriptions. The cf_stream_publish SQL function commits inside your application's SQL transaction — your INSERT/UPDATE and the real-time publish commit together. If the transaction rolls back, the real-time update never happened. No application-side outbox to maintain, no CDC pipeline.

Architecture:

  • Partitioned outbox table (cf_stream) with daily date ranges.
  • LISTEN/NOTIFY for low-latency wakeup, polling for correctness.
  • Drop-partition cleanup — vacuum-free at scale.
  • Two independent TTLs: HistoryTTL (queryable history) and HistoryMetaTTL (channel epoch).
  • HistorySize enforced at read time, not write time.

Pairs with the SDK's getState callback for the app-owned state pattern: clients load initial state from your application API, then subscribe from the captured stream position. The SDK switches paths automatically — replays from stream history on normal reconnects, calls getState only when the gap exceeds what history covers.

Docs: Engines — PostgreSQL Broker
Example: v6/pg_stream_broker — kitchen orders, multi-tenant per-restaurant channels

PostgreSQL map broker

Transactional publishing for map subscriptions. The cf_map_publish and cf_map_remove SQL functions commit inside your application's SQL transaction — write your row, publish the map update, both atomic.

Same outbox-on-Postgres foundation as the stream broker — partitioned outbox table, LISTEN/NOTIFY wakeup, daily partition retention, vacuum-free cleanup.

The map broker stores cf_map_state and cf_map_stream in your PostgreSQL database. The state lives in cf_map_* tables that Centrifugo owns, queryable from psql. Best fit when Centrifugo is the natural store for the data — feature flags, IoT device fleet telemetry, lobby rosters, collaborative cursors.

Docs: Map subscriptions — PostgreSQL

PostgreSQL controller

The control-message bus for multi-node Centrifugo (subscribe propagation, disconnects, presence pings, surveys) can now run on PostgreSQL — the same outbox-on-Postgres foundation as the brokers. Until this release, multi-node OSS Centrifugo required Redis for that bus.

With the stream broker, map broker, and controller all on PG, an OSS cluster runs with PostgreSQL as the only messaging-plane dependency. No Redis, no NATS, no separate pub/sub broker.

For applications already running Postgres for everything else, the messaging plane has what it needs.

Docs: PostgreSQL controller

Other improvements

  • PostgreSQL async consumer configuration polish (TLS config, separate notify DSN).
  • Schema regeneration and configuration defaults reviewed.

SDK support

Map subscriptions and shared poll subscriptions are currently supported on the client side only by centrifuge-js. Other SDKs continue to support stream subscriptions as before.

Migration notes

The new features are all opt-in:

  • Map subscriptions activate when you set subscription_type: "map" on a namespace.
  • Shared poll subscriptions activate when you set subscription_type: "shared_poll" on a namespace.
  • PostgreSQL brokers/controller activate when you set broker.type: "postgres", map_broker.type: "postgres", or controller.type: "postgres".

Resources

Miscellaneous

Don't miss a new centrifugo release

NewReleases is sending notifications on new releases.