Skip to main content

Cache recovery mode

Cache recovery mode in channels is designed to quickly deliver the most recent (latest) publication as the first event to the subscriber right after subscription request. This functionality allows Centrifugo channels to behave as a real-time key-value store. The feature is available since Centrifugo v5.4.0.

Cache recovery mode works best for channels where every Publication data represents the entire state required to display the real-time element.

Cache recovery mode may eliminate the need for the "fetch initial state" stage in many use cases, reducing server load and application complexity. When a client subscribes to a channel with cache recovery mode, it receives the most recent cached value immediately. Also, on every resubscription (due to network issues for example) the latest publication will also be immediately delivered.

As an example, one of Centrifugo users – AzuraCast web radio station server – uses such mode for its now playing feature, significantly reducing the load on the backend. As another example, check out this Twitter/X post.

Using cache recovery mode

To use cache recovery mode you need to properly configure channel namespace. The following conditions must be met:

Configuration example:

config.json
{
"channel": {
"namespaces": [
{
"name": "example",
"force_recovery": true,
"force_recovery_mode": "cache",
"history_size": 1,
"history_ttl": "1h"
}
]
}
}

After that you need to subscribe to a channel and trigger recovery on first connect. With bidirectional SDKs this may be done by providing an empty since object when creating a subscription (under the hood this leads to attaching recover: true to the client protocol subscribe request):

const sub = centrifuge.newSubscription('example:now-playing-12', {
since: {}
});

sub.on('publication', (ctx) => {
console.log(ctx);
})

Of course you also need to make sure you properly configured channel permissions. Then after successful subscription client will get latest publication in publication event.

Automatic cache recovery

info

Automatic cache recovery is available since Centrifugo v6.8.3.

Providing an empty since works well for bidirectional SDKs, but it has two limitations:

  • it must be done on the client side for every subscription;
  • it does not work for server-side subscriptions – especially for unidirectional clients (SSE, HTTP-streaming, unidirectional WebSocket) which only send a token and may not even know channel names (for example when subscriptions come from a connect proxy subs/channels or from a JWT).

To cover these cases the namespace option auto_cache_recover may be enabled. When it's on Centrifugo automatically initiates cache recovery for all subscriptions in the namespace (both client-side and server-side) – so the latest publication is delivered on every (re)subscribe without the client providing an empty since:

config.json
{
"channel": {
"namespaces": [
{
"name": "example",
"force_recovery": true,
"force_recovery_mode": "cache",
"auto_cache_recover": true,
"history_size": 1,
"history_ttl": "1h"
}
]
}
}

auto_cache_recover requires force_recovery and force_recovery_mode: cache to be set.

With this option a unidirectional listener whose channels are decided server-side (for example by a connect proxy) receives the latest publication per channel upon every reconnect, without knowing channel names or stream positions.

tip

For a connect proxy that wants to trigger recovery only for specific server-side subscriptions (instead of enabling it namespace-wide), the per-subscription recover: true flag can be returned in the subs map of the connect proxy result. It is the server-side equivalent of an empty since on the client.

caution

Using cache recovery mode may result in intermediary messages being lost and not delivered; only the latest publication in the channel is of interest in this mode.

The rest works very similarly to the stream recovery described in the history and recovery chapter. If there is an error when using the cache and Centrifugo can't recover state by providing the latest publication – then ctx will contain a recovered: false flag, and true in case of success.

Note that history has a retention TTL set via the history_ttl channel option. So in the case of retention expiry, or in the case of a restart of a Centrifugo node with Memory Engine – the history is cleaned up, so your application should tolerate the missing value in case of unsuccessful recovery.

Centrifugo PRO provide a feature to configure channel cache empty event proxy to notify your backend about missing publication scenario. So that you can re-populate the channel history with an actual value.

Conclusion

Cache recovery mode simplifies handling of dynamic data by reducing server requests, ensuring timely updates, and decreasing initial latency.