Usage
Explicit caching (default)
Section titled “Explicit caching (default)”Only queries you opt in with .$withCache() are cached:
const db = drizzle(env.DB, { cache: cloudflareKVCache(env.CACHE) })
// Cached with the default TTL (300s):const users = await db.select().from(usersTable).$withCache()
// Custom TTL (seconds) for this query:const posts = await db .select() .from(postsTable) .$withCache({ config: { ex: 600 } })Tagged queries
Section titled “Tagged queries”Give a query a stable tag to cache and invalidate it by name, independent of its tables:
const report = await db .select() .from(reportsTable) .$withCache({ tag: 'daily-report' })
// later — drop just that entry:await db.$cache.invalidate({ tags: 'daily-report' })Tagged entries are stored under {prefix}:t:{tag} (separate from hashed queries at {prefix}:q:{hash}).
Cache everything
Section titled “Cache everything”Set strategy: 'all' to cache every read query automatically. Each is invalidated when its tables are mutated through Drizzle.
const db = drizzle(env.DB, { cache: cloudflareKVCache(env.CACHE, { strategy: 'all' }),})
// No .$withCache() needed — this is cached automatically:const users = await db.select().from(usersTable)db.select().from(t).$withCache({ config: { ex: 600 } }) // 600scloudflareKVCache(env.CACHE, { defaultTtlSeconds: 120 })Sharing one namespace across apps
Section titled “Sharing one namespace across apps”Use prefix to namespace keys so multiple apps (or environments) can safely share a single KV namespace:
cloudflareKVCache(env.CACHE, { prefix: 'myapp:prod' })