Usage

Cache routes and server functions with practical invalidation examples.

API routes caching

Use cachedEventHandler to cache a route response in the cache storage mount.

server/api/cached-route.get.ts
import type { H3Event } from 'h3'

export default cachedEventHandler((event: H3Event) => {
  return {
    success: true,
    date: new Date().toISOString(),
  }
}, {
  maxAge: 60 * 60,
  getKey: event => event.path,
})

Server functions caching

Use defineCachedFunction for reusable computations that should share cached results across routes.

server/utils/repo-stars.ts
import type { H3Event } from 'h3'

export const getRepoStarCount = defineCachedFunction(async (_event: H3Event, repo: string) => {
  const data = await $fetch<{ stargazers_count: number }>(`https://api.github.com/repos/${repo}`)
  return data.stargazers_count
}, {
  maxAge: 60 * 60,
  name: 'ghStars',
  getKey: (_event, repo) => repo,
})

When you cache a server function in an edge environment, keep the event as the first argument so Nitro can use event.waitUntil() while the cache updates.

Route rules caching

You can also enable caching directly through Nitro route rules.

nitro.config.ts
import { defineNitroConfig } from 'nitro/config'

export default defineNitroConfig({
  routeRules: {
    '/blog/**': {
      cache: {
        maxAge: 60 * 60,
      },
    },
  },
})

Cache invalidation

Nitro stores cached entries with a key shaped like this:

`${group}:${name}:${getKey(...args)}.json`

The defaults are:

  • group: nitro
  • name: handlers for API routes, functions for cached functions, and routes for route rules

If you need to invalidate one entry manually, remove it from the cache storage mount.

await useStorage('cache').removeItem('nitro:functions:getAccessToken:default.json')

If you need to invalidate a prefix, clear it from the same mount.

await useStorage('cache').clear('nitro:handlers')

Normalizing cache keys

Nitro normalizes cache keys so they stay portable across storage backends. A route-like key such as /api/products/sale-items becomes apiproductssaleitems.

If you want to reproduce the same normalization when invalidating a key manually, use the same pattern Nitro applies internally:

function escapeKey(key: string | string[]) {
  return String(key).replace(/\W/g, '')
}
const normalizedKey = escapeKey('product/123/details')
await useStorage('cache').removeItem(`nitro:functions:getProductDetails:${normalizedKey}.json`)
Read more about Nitro cache behavior in the Nitro cache guide.