Reduce response times and database load with query-level caching integrated with the ZenStack ORM.
- 🌐 Redis Caching: Centralizes your caching to scale across different systems.
- 🖥️ Memory Caching: Simplifies caching when scale is not a concern.
- 🛟 Type-safe: The caching options appear in the intellisense for all read queries.
- ZenStack (version >=
canary) - Node.js (version >=
20.0.0) - Redis (version >=
7.0.0)- ℹ️ Only if you intend to use the
RedisCacheProvider
- ℹ️ Only if you intend to use the
npm install @visualbravo/zenstack-cache
pnpm add @visualbravo/zenstack-cache
bun add @visualbravo/zenstack-cacheimport { schema } from './zenstack/schema'
import { ZenStackClient } from '@zenstackhq/orm'
import { defineCachePlugin } from '@visualbravo/zenstack-cache'
import { RedisCacheProvider } from '@visualbravo/zenstack-cache/providers/redis'
import { MemoryCacheProvider } from '@visualbravo/zenstack-cache/providers/memory'
const client = new ZenStackClient(schema, {
dialect: ...,
}).$use(
defineCachePlugin({
// Choose only one provider.
// 1️⃣
provider: new RedisCacheProvider({
url: process.env['REDIS_URL'],
}),
// 2️⃣
provider: new MemoryCacheProvider(),
}),
)
async function getPostsPublishedByUser(userId: string) {
const publishedPosts = await client.post.findMany({
where: {
published: true,
authorId: userId,
},
// All of these are optional.
cache: {
ttl: 60,
swr: 120,
tags: [`user:${userId}`],
},
})
return publishedPosts
}You can easily invalidate multiple cache entries.
// Invalidate specific tags.
await client.$cache.invalidate({
tags: ['user:1'],
})
// Invalidate everything.
await client.$cache.invalidateAll()After performing a query, you can check where the result came from.
const publishedPostsStatus = client.$cache.status // 'hit' | 'miss' | 'stale'hit- a cache entry in thettlwindow was found, and the database was not queried.miss- a cache entry was not found, and the database was queried.stale- a cache entry in theswrwindow was found, and the database was queried in the background to revalidate it.
If the result was stale, you can choose to await its revalidation.
const revalidatedPublishedPosts = await client.$cache.revalidation as Post[]ttlreduces response times and database load by serving cached results.swrreduces response times by serving cached results, but does not reduce database load because it performs a revalidation in the background after each request.
Note
The total TTL of a cache entry is equal to its ttl + swr. The ttl window comes first, followed by the swr window. You can combine the two options to best suit the needs of your application.
MIT