Caching

Store expensive results once and serve them from memory or Redis with a type-safe API: cached values are the same model objects as the rest of your code. There is no separate cache client to set up.

Get Started

Type-safe caching

Fetching the same rows on every request can be slow and expensive, but adding a cache usually means a separate client, another serialization format, and hand-written invalidation code. That invalidation code is where stale data and subtle bugs appear.

Serverpod ships a built-in caching system: a local in-memory cache, a priority cache for hot keys, and a distributed cache backed by Redis. They work with your Serverpod models, so cached values are the same type of objects you already pass around.

How it works

1Store a value

Put any serializable model into the cache, optionally with a lifetime.

await session.caches.local.put(
  'product-$id',
  product,
  lifetime: Duration(minutes: 5),
);

2Read it back, or compute on a miss

On a miss, the handler runs, the value is cached, and the same value is returned.

var product = await session.caches.local.get(
  'product-$id',
  CacheMissHandler(
    () async => Product.db.findById(session, id),
    lifetime: Duration(minutes: 5),
  ),
);

3Invalidate when data changes

Remove the entry when the underlying data changes, so readers never see stale values.

await session.caches.local.invalidateKey('product-$id');

Local caches

An in-memory least-recently-used (LRU) cache for general use, plus a priority cache that keeps your hottest keys resident, both scoped per server.

Distributed cache

The same typed API, backed by Redis, gives every server in your cluster a shared cache for session data and expensive computed values.

var product = await session.caches.global.get<Product>('product-$id');

Type-safe values

You cache and read your own model objects, not untyped blobs, so a cached value is checked at compile time just like the objects you store in the database.

Everything included

LRU eviction with per-entry TTL
Key and group invalidation
Priority cache for hot keys
Cluster-wide distributed cache
Serializable model values
Read-through miss handlers
No separate cache client

Why Serverpod

Full-stack type safety. Cached values are your generated models, checked at compile time.
Open source. Store cached values in your own Redis instance and inspect exactly what is cached, with no proprietary layer.
Zero-configuration deployments. Ship to Serverpod Cloud and scale your cache alongside your servers.

Works with

Redis In-memory caching

Frequently asked questions

Does Serverpod support Redis?

Yes. The distributed cache is backed by Redis and shares entries across every server in your cluster.

Can I cache in memory without Redis?

Yes. The local and priority caches run in memory on each server and require no additional services.

What can I cache?

Any serializable Serverpod model, so cached values keep the same types as the rest of your code.

How does cache invalidation work?

Entries expire per-key using a TTL, and you can invalidate individual keys or entire groups on demand.

When should I not use this?

A cache is best-effort and can evict entries at any time, so it is not a primary datastore. Keep the source of truth in the database.

Stay up-to-date

Our mailing list keeps you up-to-date with new Serverpod releases and features. You will get an email about once a month or when something big is happening. We promise to keep it relevant and we have a strict no-spam policy.

© 2026 Serverpod AB
Built with Serverpod - Hosted on Serverpod Cloud