0
0
GraphqlHow-ToBeginner · 4 min read

How to Cache GraphQL Queries Efficiently

To cache GraphQL queries, use client-side caching libraries like Apollo Client or Relay that store query results locally. On the server side, implement caching with tools like DataLoader or HTTP caching headers to avoid repeated data fetching and speed up responses.
📐

Syntax

GraphQL caching involves setting up cache policies and storing query results. On the client, you configure cache behavior when creating the client instance. On the server, you can cache data loaders or HTTP responses.

  • Client-side cache: Configure cache policies like cache-first, network-only, or cache-and-network.
  • Server-side cache: Use DataLoader to batch and cache database requests or set HTTP cache headers.
javascript
import { ApolloClient, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: 'https://example.com/graphql',
  cache: new InMemoryCache(),
  defaultOptions: {
    watchQuery: {
      fetchPolicy: 'cache-first',
    },
    query: {
      fetchPolicy: 'cache-first',
    },
  },
});
💻

Example

This example shows how to set up Apollo Client with caching and how to use DataLoader on the server to cache database calls.

javascript
// Client-side Apollo Client setup
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';

const client = new ApolloClient({
  uri: 'https://example.com/graphql',
  cache: new InMemoryCache(),
});

// Query with caching
client.query({
  query: gql`query GetBooks { books { id title } }`,
  fetchPolicy: 'cache-first',
}).then(result => console.log(result.data));

// Server-side DataLoader example
import DataLoader from 'dataloader';

const bookLoader = new DataLoader(async (ids) => {
  // Simulate batch database fetch
  const books = await fetchBooksByIds(ids);
  return ids.map(id => books.find(book => book.id === id));
});

async function fetchBooksByIds(ids) {
  // Simulated DB call
  return [
    { id: '1', title: 'Book One' },
    { id: '2', title: 'Book Two' },
  ].filter(book => ids.includes(book.id));
}
Output
{ books: [ { id: '1', title: 'Book One' }, { id: '2', title: 'Book Two' } ] }
⚠️

Common Pitfalls

Common mistakes when caching GraphQL queries include:

  • Not setting the correct fetchPolicy, causing stale or no cache usage.
  • Ignoring cache invalidation, leading to outdated data shown to users.
  • Over-caching server responses without considering data changes.
  • Not batching requests on the server, causing redundant database calls.

Always balance cache freshness with performance.

javascript
/* Wrong: Using 'network-only' fetchPolicy disables cache */
client.query({
  query: gql`query GetBooks { books { id title } }`,
  fetchPolicy: 'network-only', // always fetches from server
});

/* Right: Use 'cache-first' to use cache if available */
client.query({
  query: gql`query GetBooks { books { id title } }`,
  fetchPolicy: 'cache-first',
});
📊

Quick Reference

ConceptDescriptionExample
Client Cache PolicyControls how queries use cache or networkfetchPolicy: 'cache-first'
DataLoaderBatches and caches server data fetchingnew DataLoader(batchFunction)
HTTP Cache HeadersCache responses at HTTP levelCache-Control: max-age=60
Cache InvalidationUpdate or clear cache when data changesRefetch queries or update cache manually

Key Takeaways

Use client-side caching libraries like Apollo Client with proper fetch policies to cache GraphQL queries.
Implement server-side caching with DataLoader to batch and cache database requests efficiently.
Set HTTP cache headers to leverage browser and proxy caching when possible.
Avoid stale data by managing cache invalidation carefully after data updates.
Test caching behavior to ensure data freshness and performance balance.