Skip to main content

Caching

Cache strategies

For all read queries in Prisma Client, you can define the cacheStrategy parameter that configures cache behavior. The cache strategy allows you to define two main characteristics of the cache:

  • Time-to-live (TTL): Duration in seconds a cached response is considered fresh.
  • Stale-while-Revalidating (SWR): Duration in seconds a stale cache response is considered acceptable while the cache is refreshed in the background

Time-to-live (TTL)

Time-to-Live (TTL) determines how long cached data is considered fresh. By specifying the ttl in seconds, you can control the duration for which data in the cache remains valid. When a read query is executed, if the cached response is within the ttl limit, Prisma Client retrieves the data from the cache without querying the database. If the cached data is not available or has expired, Prisma Client queries the database and stores the results in the cache for future requests.

Use ttl in cacheStrategy and specify the TTL of the query in seconds:

await prisma.user.findMany({
cacheStrategy: {
ttl: 60,
},
});

With a specified TTL of 60 seconds, the majority of requests will result in a cache hit throughout the TTL duration:

TTL

TTL is useful for reducing database load and latency for data that does not require frequent updates.

Stale-While-Revalidate (SWR)

Stale-While-Revalidate (SWR) allows you to control how long Accelerate can serve stale cache data while fetching fresh data in the background. When a read query is executed, Accelerate checks the age of the cached response against the swr duration. If the cache data is within the swr limit, Accelerate serves the stale data while simultaneously refreshing the cache by fetching the latest data from the database.

Use swr in cacheStrategy and specify the SWR of the query in seconds:

await prisma.user.findMany({
cacheStrategy: {
swr: 60,
},
});

When specifying a SWR of 60 seconds, the cache serves stale data until the cache refreshes itself in the background after each request:

SWR

Selecting a cache strategy

Caching helps you improve query response times and reduce database load. However, it also means you might serve stale data to the client. Whether or not serving stale data is acceptable and to what extent depends on your use case. ttl and swr are parameters you can use the tweak the cache behavior.

Cache strategy using TTL

Use TTL to reduce database load when stale cached data is acceptable.

Use case: Product catalog in e-commerce applications

Consider an e-commerce application with a product catalog that doesn't frequently change. By setting a ttl of, let's say, 1 hour, Prisma Client can serve cached product data for subsequent user requests within that hour without hitting the database. This significantly reduces the database load and improves the response time for product listing pages.

Cache strategy using SWR

Use SWR to respond quickly to requests with minimal stale data. While it does not reduce database load, it can improve response times significantly.

Use case: User profile in social media platforms

Imagine a social media platform where user profiles are frequently accessed. By leveraging swr with a duration of, let's say, 5 minutes, Accelerate can serve the cached user profile information quickly, reducing the latency for profile pages. Meanwhile, in the background, it refreshes the cache after every request, ensuring that any updates made to the profile are eventually reflected for subsequent requests.

Cache strategy using TTL + SWR

For very fast response times and reduced database load, use both TTL and SWR. You can use this strategy to fine-tune your application’s tolerance for stale data.

Use ttl and swr in cacheStrategy and specify the TTL and SWR of the query in seconds:

await prisma.user.findMany({
cacheStrategy: {
ttl: 30,
swr: 60,
},
});

When specifying a TTL of 30 seconds and SWR of 60 seconds, the cache serves fresh data for the initial 30 seconds. Subsequently, it serves stale data until the cache refreshes itself in the background after each request:

ttl_and_swr.png

Use case: News articles

Consider a news application where articles are frequently accessed but don't require real-time updates. By setting a ttl of 2 hours and an swr duration of 5 minutes, Prisma Client can serve cached articles quickly, reducing latency for readers. As long as the articles are within the ttl, users get fast responses. After the ttl expires, Prisma Client continues to serve the stale articles for up to an additional 5 minutes, revalidating the cache with the latest news from the database in response to a new query. This helps maintain a balance between performance and freshness.

On-demand cache invalidation

You can invalidate the cache using the $accelerate.invalidate API:

note

To programmatically invalidate cached queries, a paid plan is required. See our pricing for more details.

await prisma.user.findMany({
where: {
email: {
contains: "alice@prisma.io",
},
},
cacheStrategy: {
swr: 60,
ttl: 60,
tags: ["emails_with_alice"],
},
});

You need to provide the cache tag in the $accelerate.invalidate API:

try {
await prisma.$accelerate.invalidate({
tags: ["emails_with_alice"],
});
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
// The .code property can be accessed in a type-safe manner
if (e.code === "P6003") {
console.log(
"The cache invalidation rate limit has been reached. Please try again later."
);
}
}
throw e;
}

Default cache strategy 

Accelerate defaults to no cache to avoid unexpected issues. While caching can improve performance, incorrect usage may lead to errors.

For instance, if a query is executed on a critical path without specifying a cache strategy, the result may be incorrect, with no clear explanation. This issue often arises when implicit caching is unintentionally left enabled.

To avoid such problems, you must explicitly opt-in to caching. This ensures you are aware that caching is not enabled by default, preventing potential errors.

When no cache strategy is specified or during a cache miss, a Prisma Client with the Accelerate extension routes all queries to the database through a connection pool instance near the database region.