Prevent an Unnecessary Refetch with nextFetchPolicy and Apollo Client

I recently figured out the cause of a strange issue that was plaguing an editable table implementation written using React and Apollo Client 3.x. The problem was due to a change in how the cache-and-network fetch policy works in Apollo Client 3.

The Problem with the Fetch Policy

The table in question had many columns and displayed values that were expensive to calculate. This resulted in an initial load time of a few seconds, but that was acceptable for this application. That’s because the table’s purpose was providing a place where a user could make changes to input values and see how that affected all of the calculated values. A user could navigate to the page and wait a few seconds for everything to load. They could then stay on the page for a while making various changes without waiting for the whole table to reload again.

At least that was how it was supposed to work.

What happened was that, while a change was saved to the server, the table row would display a loading state. Then, the row would display the results from the server (as desired). And finally, in the background, the client would fire off a request to the server to refetch all of the data in the table. This resulted in extra load on the server and glitchy user interactions because the full table would re-render a few seconds after saving the last change.

The row was updating immediately upon the completion of the mutation. Because of that, I knew the updated data coming back from the server was properly populating the Apollo cache. But the whole point of sending that data back in the mutation response is to avoid doing a separate query after the mutation.

I eventually found the answer in a GitHub Issue in the apollo-client repository.

The Solution

The query that initially loaded the table data was using a fetchPolicy of cache-and-network. Apparently, as of Apollo Client 3, this fetch policy will

… read from the cache and make a network request, not just the first time, but whenever there’s a cache update that affects this query.

To prevent Apollo Client from making the network request after an update, you need to provide an additional policy:


  const { loading, error, data } = useQuery(GET_ALL_TODOS, {
    fetchPolicy: "cache-and-network",
    nextFetchPolicy: "cache-first",
    variables: {
      _size: 10
    }
  });

Setting the nextFetchPolicy to cache-first prevents the unwanted refetch after an update that affected the query. You can read more about nextFetchPolicy in the Apollo docs.

Preventing an Unnecessary Refetch with nextFetchPolicy and Apollo Client

These steps are helpful if you’re seeing an unexpected refetch of a query after an update when using Apollo Client with cache-and-network. Try setting the nextFetchPolicy to cache-first and see if that helps.