Skip to content

Usage

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 } })

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}).

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 } }) // 600s

Use prefix to namespace keys so multiple apps (or environments) can safely share a single KV namespace:

cloudflareKVCache(env.CACHE, { prefix: 'myapp:prod' })