Emulating "stale-while-revalidate" pattern with Apollo Client

I’m currently building a web application with Next.js, hosted on Vercel, using Apollo Client to query a GraphQL backend (not Apollo Server).

I’m looking for some feedback on the idea to recreate the SWR (stale while revalidate) pattern, that Vercel is currently popularizing, on top of the Apollo Cache.

We are using the “Incremental Static Regeneration” feature from Next.js to statically generate pages on Vercel as they are being accessed by users and we are very impressed with the how the SWR helps us scale the app for our static pages.

Unfortunately, we still have pages that are not static and we have sections on static pages that are dynamically being generated, requiring us to make calls to the API from the client.

So far we’ve been using Apollo Client and the built-in caching functionality to make these calls as performant as possible. Until now we used the default cache-first policy for everything, since the UI was mostly driven by data consumption. But now we are adding features to update data and running into more cases where we need to update the cache both based on changes the local user performed and based on remote users actions.

It occurred to me that it would be great if I could replicate the SWR pattern with Apollo Cache. What I imagine is having a “revalidate” variable set to a given time (30 seconds as an example). If data has been last fetched less than 30 seconds ago, I would use the cache-first strategy, but if data was last fetched more than 30 seconds ago, use the cache-and-network strategy and show potentially stale data at the same time as a network request is sent to fetch fresh data and update it in the background as data comes in.

What I’m hoping to achieve is a lower amount of requests to the API based on data being less than 30 seconds old being served out of the cache, as well as a very snappy and fast UI and the ability to tweak the performance by changing the revalidate time (I plan to expose it as an environment variable and perhaps add separate variables for different users and different scenarios, based on how I find the performance in production).

What’s your feedback on this idea. Do you think it would be useful in practice? Do you have any pointers how I should go about implementing this and do you know of any existing efforts to do something similar?

1 Like