Skip to content

Releases

v6.10.2

Choose a tag to compare

@FZambia FZambia released this 23 Oct 04:10
cf21c5d

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 (SSE), GRPC, WebTransport). Centrifugo is built around 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.

Official client SDKs are available for JavaScript (browser, Node.js, React Native), Dart/Flutter, Swift, Java, Python, Go, and .NET. In addition, Centrifugo supports a unidirectional approach for simple use cases with no SDK dependency.

For details, go to the Centrifugo documentation site. For runnable demos see centrifugal/examples.

What's changed

Improvements

  • Ed25519 public key for EdDSA tokens. New option client.token.ed25519_public_key (and the same option in client.subscription_token) takes a PEM encoded Ed25519 public key to verify EdDSA signed connection and subscription tokens. Before, EdDSA tokens could be verified only with keys from a JWKS endpoint, while RSA and ECDSA keys could already be set directly. See JWT authentication (#1288).
  • JWKS key rotation and outages no longer disconnect clients for good (#1289). See JSON Web Key support:
    • a token whose key is not returned by the JWKS endpoint (for example, during a key rollout, or a token signed with a retired key) is now treated as an expired token (109, or 3005 on unidirectional transports), so the client gets a new token and reconnects. Before, it was an invalid token (3500), and client SDKs stopped reconnecting;
    • if the JWKS endpoint can't be reached, the client gets a temporary error and retries, instead of an invalid token;
    • keys loaded from the JWKS endpoint are now kept for 5 minutes instead of one hour, so a key removed from the endpoint (for example, after a leak) stops working within 5 minutes. Keys already loaded are still used while the endpoint can't be reached;
    • the same applies to subscription tokens. Tokens with a bad signature or malformed tokens are still invalid.
  • proxy.proto now documents every message and field: what each request field carries, what each result field changes, and which responses honour error and disconnect. See also proxy docs (#1287).

Fixes

  • Node metrics interval in the info server API is the configured interval again (e.g. 60), not a slightly different measured value like 59.999856375 (centrifugal/centrifuge#671).

Miscellaneous

  • Docker image is rebuilt with the latest Alpine ca-certificates-bundle, which removes trust in the compromised eMudhra intermediate CA certificates. Centrifugo itself already rejected these certificates since v6.10.1 (Go 1.27.3), but other tools in the image which use the system trust store did not, and container scanners reported the image as vulnerable (#1290).
  • This release is built with Go 1.27.3.
  • Dependency updates.
  • See also the corresponding Centrifugo PRO release.

v6.10.1

Choose a tag to compare

@FZambia FZambia released this 20 Oct 17:45
f87906a

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 (SSE), GRPC, WebTransport). Centrifugo is built around 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.

Official client SDKs are available for JavaScript (browser, Node.js, React Native), Dart/Flutter, Swift, Java, Python, Go, and .NET. In addition, Centrifugo supports a unidirectional approach for simple use cases with no SDK dependency.

For details, go to the Centrifugo documentation site. For runnable demos see centrifugal/examples.

What's changed

This release was created to upgrade to Go 1.27.3 which addresses golang/go#82345

Miscellaneous

  • This release is built with Go 1.27.3.
  • Dependency updates.
  • See also the corresponding Centrifugo PRO release.

v6.10.0

Choose a tag to compare

@FZambia FZambia released this 19 Oct 17:40
299f97d

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 (SSE), GRPC, WebTransport). Centrifugo is built around 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.

Official client SDKs are available for JavaScript (browser, Node.js, React Native), Dart/Flutter, Swift, Java, Python, Go, and .NET. In addition, Centrifugo supports a unidirectional approach for simple use cases with no SDK dependency.

For details, go to the Centrifugo documentation site. For runnable demos see centrifugal/examples.

What's changed

Improvements

  • Stricter JSON parsing in the client protocol. Centrifugo now follows RFC 8259 exactly. It rejects invalid UTF-8, repeated keys, extra data after a message, keys with different letter case and too large integers. Before, such messages were partly accepted. Now Centrifugo and your backend always read a message the same way, and invalid UTF-8 can't reach browsers (a browser closes the WebSocket when it gets invalid UTF-8). Official SDKs are not affected. See two edge cases in the behaviour changes below (centrifugal/protocol#56, centrifugal/centrifuge#652, #1259).
  • Centrifugo now uses its own JSON code generator, cfjson, instead of easyjson (and segmentio/encoding for decoding), and its own Protobuf generator, cfprotobuf, instead of vtprotobuf. JSON output is the same byte for byte. In protocol benchmarks on Linux amd64, JSON encoding takes 46% less time and JSON decoding 25% less time (centrifugal/protocol#56).
  • Server API errors show if a retry makes sense. Errors have a new temporary field (similar to the client protocol Error field): it is true when the same request may succeed later. There is a new error 111 too many requests (HTTP 429, gRPC ResourceExhausted). Requests which can never succeed now return 107 (bad request), 102 (unknown channel) or 108 (not available) instead of 100 internal, so clients don't retry them (#1247).
  • Faster memory broker history. History is split into 64 parts by channel, each with its own lock. Before, all channels used one lock. Publishing with history into 10000 channels from all CPUs now takes 1.61Β΅s per publication instead of 2.90Β΅s (βˆ’44%) (centrifugal/centrifuge#666).
  • Faster broadcast to subscriptions with positioning: Centrifugo reads the current time once per broadcast, not once per subscriber. 10–15% faster for 100 and 1000 subscribers (centrifugal/centrifuge#665).
  • Unidirectional SSE no longer copies every message when writing it to a connection. With a 1 KB payload, memory allocated per delivered message dropped from about 1,220 bytes to 58 bytes, and with a 10 KB payload from about 10,650 bytes to 330 bytes. Garbage collection almost stops in these tests, and CPU usage is a few percent lower. Unidirectional HTTP streaming also allocates a bit less per message. Thanks @darakanoit (#1251).
  • Broadcast with publication_data_format json or json_object checks the data once per broadcast, not once per channel. A broadcast into 1000 channels with a 10 KB payload uses 60% less CPU (7.35 ms β†’ 2.94 ms) and is 33% faster; with a 1 KB payload it uses 17% less CPU. Thanks @darakanoit (#1252).
  • Faster JWKS token verification under load. A JWKS cache hit no longer takes a lock or allocates memory. Parallel connect token verification is 34% faster with RSA-2048 keys (4.76 Β΅s β†’ 3.13 Β΅s) and 15% faster with ES256 keys. Thanks @darakanoit (#1253).
  • PostgreSQL stream and map brokers no longer allocate memory on an empty outbox poll. On an idle server, the stream broker allocated 25.8 MiB per second and the map broker 11.6 MiB per second; now both allocate about 130 KiB per second, with no garbage collection cycles. Thanks @darakanoit (#1250).
  • Config reload on SIGHUP improvements. Before, if a subscription token setting failed to apply, the connection token settings were already changed, and Centrifugo worked with a mix of old and new settings (#1267).
  • Redis IAM authentication (experimental). Centrifugo can connect to managed Redis/Valkey with short-lived cloud tokens instead of a static password: aws_iam_auth for Amazon ElastiCache (node-based and Serverless), gcp_iam_auth for Google Cloud Memorystore and azure_entra_auth for Azure Managed Redis and Azure Cache for Redis. Credentials come from the cloud default chain (AWS SDK credentials, Google Application Default Credentials, DefaultAzureCredential), tokens are refreshed automatically. The options work everywhere Redis is configured: engine, broker, presence manager, map broker, Redis stream consumer. See Redis IAM authentication (#1118, #1283, centrifugal/centrifuge#670).
  • JWKS keys are updated after key rotation. Centrifugo loads keys from the JWKS endpoint again one hour after the last load. A key removed from the endpoint stops working within one hour. Before, a key which was used all the time was never loaded again. Also, tokens with unknown kid values now share one request to the JWKS endpoint, so fake tokens can't overload it (#1255, #1264).

Behaviour changes

Most setups need no changes. Please check this list before upgrading:

  • Publication data for JSON subscribers must be valid UTF-8 JSON. If you publish invalid UTF-8, or binary data (gRPC data or HTTP b64data) into a channel with JSON subscribers, they are disconnected with code 3506 (centrifugal/centrifuge#652).
  • Async consumers retry only temporary errors (100 and 111). For other errors, Centrifugo logs the error and marks the message as processed (#1247).
  • Client publish into a namespace with a non-stream subscription type (map, map_clients, map_users, shared_poll) is now refused with 103 permission denied (#1280).
  • Join/leave override in a subscription token now works. If the token sets join_leave: true and the namespace has join_leave off, the client gets join/leave messages when it asks for them and has presence permission. Before, Centrifugo checked only the namespace option (#1277).
  • Nats raw mode: if a channel has publication_data_format set to json or json_object, messages which don't match it are not delivered (#1258).
  • A connection token with invalid b64info is now an invalid token. The client is disconnected. Before, it reconnected again and again with the same token. An invalid pattern in the channels server API call now returns 107 (bad request) instead of 100 (internal error) (#1267).

Fixes

  • Join/leave, positioning and recovery requested by a client now work for subscriptions allowed by the subscribe proxy. Join/leave also works for subscribe stream proxy subscriptions. Permission checks are the same as for other subscriptions. Thanks @AdzerKI (#1270, #1277).
  • A connection without user ID could subscribe to a user-limited channel with an empty user in it, such as user# or user#42,. Now it can't. Channels requested on connect are no longer subscribed in a namespace with subscribe stream proxy or with a non-stream subscription type (#1279, #1280).
  • Subscribe stream proxy fixes (#1262, #1272):
    • closing the stream of an old subscription no longer unsubscribes a new one;
    • a refused stream subscription no longer keeps a goroutine until disconnect;
    • a first message which comes at the same moment as the timeout no longer leaves the subscription on a closed stream.
  • With client.concurrency, disconnect no longer waits for a timeout if the client goes away while its subscribe waits in the queue (#1268).
  • A null item in a shared poll refresh proxy response, or null channel options in connect proxy subs, no longer crash Centrifugo (#1265, [centrifugal/centrifuge#647](https://github...
Read more

v6.9.7

Choose a tag to compare

@FZambia FZambia released this 29 Sep 04:29
a2e0896

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 (SSE), GRPC, WebTransport). Centrifugo is built around 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.

Official client SDKs are available for JavaScript (browser, Node.js, React Native), Dart/Flutter, Swift, Java, Python, Go, and .NET. In addition, Centrifugo supports a unidirectional approach for simple use cases with no SDK dependency.

For details, go to the Centrifugo documentation site. For runnable demos see centrifugal/examples.

What's changed

Improvements

  • Publications into a channel are no longer delayed by clients subscribing to it with recovery or positioning (see also the fix below). In a benchmark which publishes into a channel with 100 subscribers while other clients connect with it and a second channel whose history read takes 1ms, publish latency dropped from 249Β΅s to 28Β΅s on average and from 1240Β΅s to 46Β΅s at p99. Broadcasting to a client which is not subscribing to anything now costs an atomic load instead of a mutex and a map lookup (a broadcast to 100 subscribers went from 27.4Β΅s to 23.9Β΅s).
  • Faster fossil delta encoding – Centrifugo now uses centrifugal/fdelta package instead of shadowspore/fossil-delta. Creating a delta is 3.5-4.2x faster on JSON payloads and allocates once instead of five times (128 B/op at 16 KiB against 19 KB). centrifugal/centrifuge#638.
  • Less memory per connection. Client command handlers copied the whole configuration (about 10 KB) onto the stack of the connection's goroutine, so the stack grew on the first commands. They now read it by reference. With 20k connections which connect and subscribe, stack memory is 35% lower and process RSS about 20% lower – about 10 KB less per connection (#1244).
  • Faster channel options lookup. Options are now resolved for every namespace once – on start and on every config reload – so a lookup is a map read without allocation. Before, Centrifugo cached the options of 1024 channels, and with more channels in use (a broadcast into thousands of channels, many personal channels) lookups kept missing the cache and allocated a copy of the options each time. A broadcast into 1000 channels is 27% faster and allocates about half the memory (#1245).
  • Less work per broadcast when delta compression is used by JSON clients. A JSON client receives a delta as a JSON string, so a delta may only be built when the previous payload is valid UTF-8. Now a payload is scanned at most once per broadcast, and not at all when no JSON client takes deltas. It only matters for payloads carrying non-ASCII text (utf8.Valid has an ASCII fast path) – on such payloads the broadcast is 12-21% faster depending on the number of encoding combinations in the channel (centrifugal/centrifuge#637).

Fixes

  • Fix a possible node deadlock when a client subscribes to a channel with recovery or positioning enabled. Such a subscription kept its recovery buffer locked until the subscribe result was written, while a publication into the channel waited for that buffer holding the hub shard lock – so publications, subscribes, unsubscribes, disconnects and graceful shutdown for all channels of that shard could block. Publications no longer wait for a subscribing client (centrifugal/centrifuge#640). Reported in GHSA-xcch-wm46-g65g by @EJ-Research
  • Delta compression and publication tags filters are documented as mutually exclusive, but Centrifugo still negotiated delta for a subscription with a tags filter. To keep the chain of deltas intact, publications filtered out for such a subscriber were sent to it anyway – so the filter was not applied at all. Delta is no longer negotiated for subscriptions with a tags filter (centrifugal/centrifuge#634).
  • Map channels: when a channel's stream expired while its top offset and epoch survived, a read since an older offset returned an empty result with no error – recovery reported recovered: true while silently skipping the lost publications. Such a read now results in an unrecoverable position error, so clients resync from the full state (centrifugal/centrifuge#636).
  • Publications buffered while a client subscribes with recovery or positioning are now limited by client.queue_max_size per connection. Before, each subscription got the whole limit for itself, so a client subscribing to many channels at once – for example with server-side subscriptions on connect – could hold many times that limit in memory (centrifugal/centrifuge#641).
  • Redis Cluster: a channel whose name starts with } made the keys of that channel land in different slots, which could crash the node – for example when a client subscribed to such a channel with recovery. Such channels are now refused with a bad request error (centrifugal/centrifuge#645).
  • The unsubscribe server API method now returns a bad request error when channel is empty, as documented. Before, it unsubscribed nothing but still sent the targeted connections an unsubscribe push for an empty channel (#1238).

Miscellaneous

  • This release is built with Go 1.26.8.
  • Dependency updates.
  • See also the corresponding Centrifugo PRO release.

v6.9.6

Choose a tag to compare

@FZambia FZambia released this 14 Sep 17:29
f2e575f

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 (SSE), GRPC, WebTransport). Centrifugo is built around 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.

Official client SDKs are available for JavaScript (browser, Node.js, React Native), Dart/Flutter, Swift, Java, Python, Go, and .NET. In addition, Centrifugo supports a unidirectional approach for simple use cases with no SDK dependency.

For details, go to the Centrifugo documentation site. For runnable demos see centrifugal/examples.

What's changed

Fixes

  • A client-side subscription refresh with an already expired subscription token was accepted. The subscription's expiration time was then cleared, so the subscription never expired. Now Centrifugo closes the connection with the 3006 (subscription expired) disconnect code. The client reconnects, gets a token expired error on resubscribe and requests a new token – all official SDKs already handle this (centrifugal/centrifuge#627).
  • Fossil delta compression with recovery: when a subscribe with recovery found no missed publications, the next publication was still sent as a delta. The client had no base data for it, so it could not decode that publication or any after it. Now the first publication after such a subscribe is sent with full data (centrifugal/centrifuge#629).
  • Align fossil deltas to UTF-8 character boundaries for JSON clients centrifugal/centrifuge#630. For a change inside a multi-byte character it copies the first bytes of the character from the previous data and inserts the rest. The inserted bytes aren't valid UTF-8, json.Escape replaces them with U+FFFD, and the client fails to apply the delta. The fix eliminates this.

Miscellaneous

  • This release is built with Go 1.26.8.
  • Dependency updates.
  • See also the corresponding Centrifugo PRO release.

v6.9.5

Choose a tag to compare

@FZambia FZambia released this 13 Sep 05:53
34560b8

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 (SSE), GRPC, WebTransport). Centrifugo is built around 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.

Official client SDKs are available for JavaScript (browser, Node.js, React Native), Dart/Flutter, Swift, Java, Python, Go, and .NET. In addition, Centrifugo supports a unidirectional approach for simple use cases with no SDK dependency.

For details, go to the Centrifugo documentation site. For runnable demos see centrifugal/examples.

What's changed

Improvements

  • Slightly less work when recording centrifugo_client_ping_pong_duration_seconds – the histogram observer is now cached instead of being looked up on every pong.

Fixes

  • Fix possible panic in the channel options cache on long-running nodes. Its internal counter overflowed int32 after enough cache misses, which gave a negative slot index and crashed the node with index out of range (#1227).
  • Map subscriptions: the subscribe reply did not include expires/ttl, so clients could not refresh the subscription token in time. Also, if the map state was loaded in several pages, the client's subscription refresh was rejected with a bad request disconnect. A subscription whose expiration time was already in the past was accepted (centrifugal/centrifuge#626).
  • allowed_origins patterns with upper-case letters (e.g. https://App.Example.com) never matched, because the request Origin was lower-cased before matching and the pattern was not. Patterns are now matched case-insensitively (#1230).
  • client_name was ignored for Redis used by redis_stream async consumers (#1229).
  • PostgreSQL engine: handle one more case of several nodes creating the schema at the same time – a node could fail on start with type ... already exists (SQLSTATE 42710) (#1231).
  • The centrifugo_client_subscriptions_accepted metric was registered but never incremented, so it always showed zero (centrifugal/centrifuge#622).
  • The client closed or unsubscribed after adding subscription message is now logged at info level instead of error. It happens when a client goes away while its subscription is still being set up – this is expected and is not a server error (centrifugal/centrifuge#621).

Miscellaneous

  • We’ve updated the official Centrifugo dashboard. It covers all exposed metrics in v6.9.4, avoids deprecated Prometheus summaries, and includes descriptions for all panels. You can download it from grafana.com. See also Centrifugo's observability docs
  • This release is built with Go 1.26.8.
  • Dependency updates.
  • See also the corresponding Centrifugo PRO release.

v6.9.4

Choose a tag to compare

@FZambia FZambia released this 07 Sep 05:07
4b85416

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 (SSE), GRPC, WebTransport). Centrifugo is built around 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.

Official client SDKs are available for JavaScript (browser, Node.js, React Native), Dart/Flutter, Swift, Java, Python, Go, and .NET. In addition, Centrifugo supports a unidirectional approach for simple use cases with no SDK dependency.

For details, go to the Centrifugo documentation site. For runnable demos see centrifugal/examples.

What's changed

Improvements

  • New centrifugo_transport_frame_size metric – a histogram of frame sizes received from client connections. One frame may contain several commands, so this can't be calculated from the existing per-command counters. Helps to choose a good value for websocket.message_size_limit, which is applied to the whole frame (centrifugal/centrifuge#620).
  • Faster Protobuf client protocol command encoding: ~2.1x faster and ~55% less memory alloc
  • Less work on every client command: config accessors and the channel options cache no longer copy structs on each call (#1215).
  • PostgreSQL broker, map broker and controller now validate table_prefix on start. A prefix with a hyphen, space or dot used to produce a confusing syntax error inside a generated CREATE statement (#1223).

Fixes

  • Async consumers: a context.Canceled error returned by the message dispatcher was treated as a shutdown signal. In the Kafka consumer this could skip records and then commit an offset after them, losing messages. This did not happen right now in Centrifugo, but inaccurately introduced code could cause this in the future. Fixed for Kafka and SQS (#1221).
  • fix(pgoutbox): tolerate 42P07 when another node creates the partition first #1220. Thanks to @AlexeyShalaev for bringing and fixing this.
  • PostgreSQL engine: handle the case when several nodes create the schema at the same time. Before that a node which lost the race could fail to start with error initializing Postgres ... schema.
  • PostgreSQL map broker: the fast path in EnsureSchema never worked, so every node start ran the full DDL batch again. It works now and also refreshes the partition lookahead (#1223).
  • Fix a race in log throttling of the connection limit check – it could print many duplicate warnings instead of one per throttle interval (#1214).
  • Some config validation errors mentioned keys which don't exist, so it was hard to find the option to fix (#1213).
  • Admin web UI: fix uptime formatting on the Status page (centrifugal/web#71).

Miscellaneous

  • This release is built with Go 1.26.8.
  • Dependency updates.
  • See also the corresponding Centrifugo PRO release.

New Contributors

Full Changelog: v6.9.3...v6.9.4

v6.9.3

Choose a tag to compare

@FZambia FZambia released this 23 Aug 06:45
e108c4e

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 (SSE), GRPC, WebTransport). Centrifugo is built around 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.

Official client SDKs are available for JavaScript (browser, Node.js, React Native), Dart/Flutter, Swift, Java, Python, Go, and .NET. In addition, Centrifugo supports a unidirectional approach for simple use cases with no SDK dependency.

For details, go to the Centrifugo documentation site. For runnable demos see centrifugal/examples.

What's changed

Improvements

  • Faster and less allocating decoding of client commands. The command decoders are on the hot path – one is taken from the pool for every frame a client sends. The JSON decoder now reuses its buffered reader instead of allocating a new 4KB buffer per frame, and returns commands without allocating a slice per command when they fit into the read buffer. The Protobuf decoder unmarshals small messages straight out of the buffered reader instead of copying them into a scratch buffer first. Decoding a frame with a single JSON command got 62% faster with 93% less memory allocated, a frame with 8 commands – 25% faster with 67% less memory; for Protobuf the win is around 7-10% in time (centrifugal/protocol#41).
  • The message size limit is now applied to every command in a JSON frame. Previously it was only checked reliably for the first command, so subsequent commands in the same frame could exceed the configured limit (up to roughly twice it). A command of exactly the limit is still accepted wherever it sits in the frame (centrifugal/protocol#41).

Fixes

  • Fix client.connection_rate_limit: the configured value was used as the token bucket burst only, while the sustained rate was one connection per second. Centrifugo now accepts the configured number of new connections per second, keeping the configured value as the burst size too. Thanks to @moses-mbaga for the fix (#1207).
  • Shared poll: hmac_previous_secret_key_valid_until was compared against the iat claim carried inside the track signature. That value is chosen by whoever mints the signature, so anyone retaining the rotated-out key could keep producing accepted signatures indefinitely by backdating iat. The cutoff is now enforced against server time before consulting the previous verifier – the same way it works for the previous JWT HMAC key – with the iat check kept as an additional constraint inside the grace period (#1209).
  • Apply publication_data_format on all publication paths. It was only enforced for stream publishes (API publish, API broadcast, client publish), so map publish, shared poll publish and client map publish stored whatever bytes the caller sent. Data returned by publish, map publish and shared poll refresh proxies is now validated as well – a proxy can replace the data a client sent, and a shared poll refresh result reaches subscribers without ever passing through a client (#1210).

Miscellaneous

  • This release is built with Go 1.26.7.
  • Dependency updates.
  • See also the corresponding Centrifugo PRO release.

New Contributors

Full Changelog: v6.9.2...v6.9.3

v6.9.2

Choose a tag to compare

@FZambia FZambia released this 18 Aug 05:15
2db3c26

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 (SSE), GRPC, WebTransport). Centrifugo is built around 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.

Official client SDKs are available for JavaScript (browser, Node.js, React Native), Dart/Flutter, Swift, Java, Python, Go, and .NET. In addition, Centrifugo supports a unidirectional approach for simple use cases with no SDK dependency.

For details, go to the Centrifugo documentation site. For runnable demos see centrifugal/examples.

What's changed

Improvements

  • Connection runtime stability, consistency, and performance improvements coming from the underlying Centrifuge library. Under connection churn and concurrent subscribe/unsubscribe on the same channel, Centrifugo now keeps its internal subscription state consistent, fixes several resource and presence leaks, and avoids possible metric drift. The periodic presence updates also use noticeably less CPU and memory. As part of this work some internal operations became up to 500x faster under certain conditions (centrifugal/centrifuge#590).
  • Less memory allocation and garbage collection pressure on the message broadcast path. This mostly helps nodes that deliver many messages per second (centrifugal/centrifuge#598).
  • Kafka consumer: copy fetched records into a compact slice before putting them into the internal partition queue. Previously the queued records could keep the whole underlying fetch buffer in memory, so memory usage grew more than expected when a consumer was lagging behind (#1195).
  • Redis: read commands now fail within the expected time when Redis is unreachable, instead of silently retrying until Redis comes back. This makes behavior during a Redis outage predictable and matches how writes already worked (#1191 and centrifugal/centrifuge#591).
  • Redis: bound the worst-case time to detect a silently stalled connection (the peer stops replying but the TCP connection stays open) to under 5 seconds by tuning the keepalive (#1192 and centrifugal/centrifuge#592).
  • Redis: verify PUB/SUB delivery with liveness probes to detect a broken subscription connection earlier (centrifugal/centrifuge#594).
  • Add per-IP throttling of failed attempts on the admin password login endpoint (POST /admin/auth) to slow down brute-force. A valid login is not affected, even while an attack is in progress. This is best-effort protection only – the admin endpoint should still be protected at the infrastructure level (firewall rules, private network, authenticating reverse proxy) (#1204).
  • Harden the binary (Protobuf) protocol frame decoder so that a crafted length prefix can no longer make the server allocate too much memory. The configured message size limit is now always applied when reading client commands (#1203 and centrifugal/centrifuge#612).
  • Redis Sentinel: the Sentinel client now periodically refreshes its topology, so changes such as a new master after a failover are picked up more reliably (#1201 and centrifugal/centrifuge#611).
  • Redis Sentinel: Centrifugo also inherited several important Redis Sentinel setup stability improvements from the updated rueidis client (v1.0.77 release notes).

Fixes

  • Fix a possible server process crash (nil pointer panic) that could happen when a delta publication failed to encode to JSON. The broadcast goroutine could panic and terminate the whole node (centrifugal/centrifuge#597).
  • Fix a case where a client could end up with several concurrent connections on the server under Redis load. On disconnect the transport is now closed before the per-channel cleanup, so a slow Redis no longer delays the socket teardown of the old connection (centrifugal/centrifuge#595).
  • Async consumers: do not acknowledge messages that were still being consumed during shutdown, so such messages are re-delivered later instead of being lost (#1196).
  • Logging: raise the internal log handler buffer from 64 to 1024 to reduce the chance of blocking on logging under bursts (#1190).

Miscellaneous

  • This release is built with Go 1.26.6.
  • Dependency updates.
  • We detached App-owned state with stream subscriptions to its own blog post. It was part of PostgreSQL stream broker post before, but the mechanism is generic and not only PostgreSQL specific - so it's better to have it separate.
  • Base Docker image updated to Alpine 3.24 (#1194).
  • See also the corresponding Centrifugo PRO release.

v6.9.1

Choose a tag to compare

@FZambia FZambia released this 13 Jul 06:22
4603be2

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 (SSE), GRPC, WebTransport). Centrifugo is built around 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.

Official client SDKs are available for JavaScript (browser, Node.js, React Native), Dart/Flutter, Swift, Java, Python, Go, and .NET. In addition, Centrifugo supports a unidirectional approach for simple use cases with no SDK dependency.

For details, go to the Centrifugo documentation site. For runnable demos see centrifugal/examples.

What's changed

Improvements

  • Possibility to choose color accents in admin web UI.

Fixes

  • Admin web UI: add previously missing API commands to the web UI – map API (map_publish, map_remove, map_read_state, map_read_stream, map_stats, map_clear), shared poll API, etc. – and update the embedded web UI (#1184, commit 3fc933d9).
  • Fix a WARN log about a missing dev key on start – some options and flags left over from the dev page removed in v6.9.0 were not fully cleaned up (#1185, commit 8cee857f).
  • Admin: drop the undocumented and unused fallback that read the admin auth token from a token URL query parameter – the token must be supplied via the Authorization header (#1187, commit bc33546f). Addresses GHSA-v4h4-9j4c-ghgp
  • Removed an unused map ordered option (#1186, commit 8752f242).

Miscellaneous