# Serverpod Caching

> Serverpod caching — local and Redis caches, cache keys, lifetime, CacheMissHandler. Use when caching data, optimizing queries, or working with session.caches.

- Skill: `serverpod/serverpod-caching` (Agent Skill)
- Install (CLI): `npx skillmds@latest add serverpod/serverpod-caching`
- Raw SKILL.md: https://api.skillmd.com/api/skills/serverpod/serverpod-caching/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: serverpod (https://skillmd.com/u/serverpod)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/serverpod/serverpod-caching

---


# Serverpod Caching

In-memory and optional Redis caches via `session.caches`. Cached objects must be serializable models or primitives supported by Serverpod.

## Cache types

- **`session.caches.local`** — in-memory, current server instance
- **`session.caches.localPrio`** — in-memory, for frequently accessed entries
- **`session.caches.global`** — Redis-backed, shared across instances (requires Redis config; do not use without Redis enabled)
- **`session.caches.query`** — local query cache used by generated database helpers

## Basic usage

```dart
await session.caches.local.put('UserData-$userId', userData,
  lifetime: Duration(minutes: 5));

var userData = await session.caches.local.get<UserData>('UserData-$userId');
```

## CacheMissHandler

Load on miss and store automatically:

```dart
var userData = await session.caches.local.get(
  'UserData-$userId',
  CacheMissHandler(
    () async => UserData.db.findById(session, userId),
    lifetime: Duration(minutes: 5),
  ),
);
```

Returns `null` if the handler returns `null` (nothing stored).

## Collections and primitives

```dart
await session.caches.local.put('userCount', 17, lifetime: Duration(minutes: 5));
var count = await session.caches.local.get<int>('userCount');
```

If relevant set a **lifetime** to avoid unbounded growth. Use stable, unique keys (e.g. `'EntityName-$id'`).

## Pitfalls

- `session.caches.global` asserts Redis is enabled; it is not a safe no-op fallback.
- Cache groups (`put(..., group: 'name')` + `invalidateGroup('name')`) only work on the local caches. `invalidateGroup` throws `UnimplementedError` on the Redis-backed global cache, so invalidate those entries by key with `invalidateKey`.

