Implementing Caching Strategies

1. Understanding Cache Levels

LevelWhere
BrowserApollo InMemoryCache, urql
CDN/EdgeCloudflare, Fastly via GET + APQ
App-levelRedis response cache
ResolverPer-field memoization
DatabaseQuery plan cache, materialized views

2. Using Response Caching

Example: Yoga response cache

import { useResponseCache } from "@graphql-yoga/plugin-response-cache";

createYoga({
  schema,
  plugins: [useResponseCache({
    session: (req) => req.headers.get("authorization"),
    ttl: 60_000,
    invalidateViaMutation: true
  })]
});

3. Implementing Cache Control

Directive ArgDetail
maxAgeSeconds to cache
scopePUBLIC | PRIVATE
inheritMaxAgeUse parent's maxAge

4. Setting Cache Hints

Example: Apollo cacheControl

products: (_, args, { cacheControl }) => {
  cacheControl.setCacheHint({ maxAge: 300, scope: "PUBLIC" });
  return db.product.findMany();
}

5. Using ETags

AspectDetail
GenerationHash response body
ValidationClient sends If-None-Match → 304 on hit
Persisted QueriesHash already exists; ideal pairing

6. Implementing Field-level Cache

PatternDetail
Per-field memoCache resolver result by (id, args)
Read-throughCheck cache, fall back to DB, populate
TTLShort for hot fields, long for static

7. Using Redis Cache

Example: Redis-backed loader

const loader = new DataLoader(async (ids) => {
  const cached = await redis.mget(ids.map(k => `user:${k}`));
  const missing = ids.filter((_, i) => !cached[i]);
  if (missing.length) {
    const fresh = await db.user.findMany({ where: { id: { in: missing } } });
    await Promise.all(fresh.map(u => redis.set(`user:${u.id}`, JSON.stringify(u), "EX", 300)));
  }
  return ids.map((id, i) => cached[i] ? JSON.parse(cached[i]) : fresh.find(u => u.id === id));
});

8. Implementing Cache Invalidation

StrategyDetail
Time-based (TTL)Simple; tolerate staleness
Event-basedInvalidate on mutation publish
Tag-basedTag entries with entity ids; purge by tag
Versioned keysBump version on write

9. Using Cache Keys

ComponentExample
Query hashSHA256 of operation
VariablesStable JSON serialization
SessionUser id (for PRIVATE) or anon
Schema versionInvalidate on schema change

10. Configuring Cache TTL

ContentTTL
Reference data (countries)1 day+
Catalog (product info)5–30 min
User profile1–5 min
Live counts10–60 s
Personal feeds0 (no cache)