← Back to Blog

Speed and Savings: Caching Database Queries with Prisma

Jon Harrell
Jon Harrell
May 24, 2024
Updated July 9, 2026

Query caching stores the result of a database read so repeated requests are served from the cache instead of hitting your database: faster responses, lower database load, and infrastructure that survives traffic spikes. Prisma Postgres builds this in at the query level: you add a cacheStrategy to an individual Prisma ORM query and choose how long results stay fresh, with no separate caching layer to deploy or invalidate. This post covers why and when to cache, and how per-query caching works in practice.

Updated (July 2026): This post originally covered caching through Prisma Accelerate as a standalone product. Query caching with TTL and SWR is included as part of Prisma Postgres, so the post now describes it in that context. The concepts and the per-query API are unchanged.

Picture this: you and your team just released your latest app, SuperWidget. Everyone is excited, and you're pretty sure it's going to be a hit... and it is! SuperWidget is suddenly used by every major company in the world. However, you quickly realize that the level of traffic far outweighs what you planned for, and your app is starting to have degraded performance.

To solve this, your team jumps into action. You dive into your application monitoring and realize that several queries in your application have a much larger impact than anticipated. After a long night, your team implements a number of infrastructure improvements, most notably a caching layer, which takes the load off the rest of your infrastructure. SuperWidget performance recovers, and your new customers are happy with their experience.

So, what could you and your team have done better?

While your team was capable, fire drills and all-nighters are the last thing you want. The solution still required a coordinated effort and a lot of engineering hours. Per-query caching built into your database layer removes most of that work.

Why you should cache database queries

As the example shows, caching helps when you need to reduce database or application load. By caching, you remove expensive operations from the time it takes to load your application, also known as the "critical path". Subsequent requests use the cached data and avoid spending app or database time computing the result. Reduced load also means your infrastructure can support a higher workload, or your app can run on smaller hardware, which saves money.

An image showing a large number of connections going from clients, to a server, to a database. The database is overloaded and stuck at 100% CPU. There is an X's for eyes emoji next to the database.

An image showing a large number of connections going from clients, to a server, through a cache, to a database. Thanks to the cache, the database is not overloaded. There is an emoji with sunglasses next to the database.

Another common reason to cache is egress cost: many cloud database providers charge for data leaving their service, so serving repeated reads from a cache cuts that line item. (On Prisma Postgres, egress is included on every plan, so the motivation there is speed and load rather than transfer fees.)

Faster load times and reduced costs lead to a third benefit: improved perception of your application. Quicker loads make a more enjoyable experience, and an app that feels sluggish leads to users spamming refresh at best and leaving for good at worst.

Caching is delivered through the Prisma Postgres client extension; enable it once on your client (see the caching docs for the exact setup for your Prisma version), then caching a problematic query is a per-query decision:

const myExpensiveQuery = await prisma.widget.findMany({
  cacheStrategy: {
    ttl: 60 * 5, // serve from cache for 5 minutes
    swr: 60 * 2, // serve stale for 2 more minutes and revalidate in the background
  },
  // [...]
})

ttl (time to live) controls how long a result is served as fresh. swr (stale-while-revalidate) serves the stale result for an additional window while the cache refreshes in the background, so users get fast responses even at the moment the data expires. You can use either alone or combine them; the caching docs cover the trade-offs.

When to cache

Now that you know why and how to cache, you may be tempted to cache every query. Before you do, note what happened in the example: the team monitored the application before implementing caching.

Caching is a trade, and any addition can incur a cost or cause unintended side effects. At Prisma, we're big fans of observability-driven development: instrument your app and make informed decisions. If a query must always return exactly up-to-date data, caching is probably the wrong fit. Data that changes rarely, or that tolerates a short staleness window, is a great fit.

This isn't to say you need production traffic before caching anything. Caching helps during development too: if automated tests reveal a slow query, add a cacheStrategy to it and measure the difference. Regardless of environment, the advice is the same: measure and benchmark, make a change, then measure again.

What per-query caching saves you

Because caching is decided per query, the rest of your application continues to run as-is, and you can adopt it one hot spot at a time. The alternative is running your own caching infrastructure: a managed key-value store still leaves you inserting data, managing indexes and replication, and invalidating entries when things change. With caching built into the database layer, you enable the extension once and then add a cache strategy per query, rather than running a cache service of your own.

An image with two emoji. On the left is an emoji that looks dizzy and overwhelmed. Surrounding it are a lot of things that you have to think of when managing caching infrastructure: Redis, memcached, indexes, invalidation, in-memory, sharding, AWS, GCP. The emoji on the right is winking, clearly happy. It has two steps above it: 1. find a query to cache. 2. Use the cacheStrategy feature.

Workloads where query caching shines

  • Static content, such as blog posts
  • Complex queries, such as usage calculation for billing tasks
  • Read-heavy applications, such as social media platforms, news aggregators, and e-commerce sites

Per-query caching also suits teams that onboard engineers often: because the cache lives in the query itself, a new team member can see exactly what is cached and for how long by reading the code.

Frequently asked questions

Wrapping up

Caching remains one of the genuinely hard problems of software engineering. Caching more things won't solve problems by itself; a team needs to understand what can be cached and how it impacts their product.

With caching built into Prisma Postgres on a per-query basis, the implementation part stops being the hard part, and you can spend the time on the decisions instead. Create a database with npx create-db, add a cacheStrategy to your hottest query, and measure the difference.

Looking ahead: Prisma Next is a TypeScript-native rewrite of Prisma ORM, built for AI coding agents and currently in early access. It becomes Prisma 8 at general availability; until then, Prisma 7 stays the production choice. To try it, run npm create prisma@next or read the early access docs.

Keep reading

Build your next app with Prisma

Start free. Scale when you’re ready.

Try Prisma
Share this article