Re-engineering a Pusher app to serve initial state with cache channels


Learn how to re-engineer your existing Pusher Channels apps to serve initial state using our new channel type, cache channels.


Cache channels allow your client to receive the latest message sent to a Pusher channel as soon as the client subscribes. This means you no longer need to handle the retrieval of the current state when a client connects to your app. Using cache channels to deliver initial state reduces the time to receive the first event and should simplify your code.

In some cases you can even remove all state management from your server and delegate this to the cache channel.

The existing pattern

Before now, clients loading your app would not receive any information about the current state until the app itself requested that information. For example, in a sports scores app, the app would not know the current score until it fetched this information from your server.

This meant that you would need to implement an API endpoint to lookup the necessary information and return it to the client.

Take a look at the code below for a typical jQuery implementation which uses this client to server fetch pattern when the page is loaded:

2window.onload = function () {
3 $.get('/history").success(function(response) {
4       stateData = response
5       // here you would now display the new stateData to your user
6      })
7    stateData = row
9 //return found state
10 res.send(stateData).status(200);
14app.get('/history', function(req, res) {
15    //query current state
16  db.get(sql,params, (err,row) => {
17    stateData = row
19 //return found state
20 res.send(stateData).status(200);

Here you can see that the client makes a request to an exposed endpoint on your server. In turn, your server looks up the current state from a database and then returns this to the client. This code is in addition to the Pusher Channels implementation for receiving realtime updates to the state.

The new method

With cache channels you can receive the cached event upon subscription, reducing the amount of code required and reducing the time for the client to populate the UI with data. Here’s an example of a cache channel implementation:

2var cacheChannel = pusher.subscribe('cache-channel')
3cacheChannel.bind('new-event', (data) => {
4  console.log(event received: ${data})
5  // here you would now display the new stateData to your user

You might have noticed that, alongside being a simpler implementation to the fetch method described above, this looks very similar to a normal Channels implementation. This is by design: with only a channel name change you can begin using cached channels without any additional changes.

What happens if my channel cache is empty when a client subscribes?

When your client subscribes to a cache channel and there is no cached value available, called a cache miss, Pusher Channels will notify your client by sending a pusher:cache_miss event to the channel. Your client can bind to this event to handle such cases.

1cacheChannel.bind('pusher:cache_miss',() => {
2       console.log(`cache miss`);

Channels also provides an optional webhook for cache misses. This can be used to notify your server of the cache miss, so your server can populate the cache once more by triggering an event.

You can read more about handling cache miss cases here.

Learn more about Channels – Pusher’s low-latency, pub/sub API – or sign up to begin delivering realtime events to your users at scale.