# Caching Loaders

App routes can cache a rendered response, loader data, or both. Cache behavior
is declared on the route:

```tsx
export const config = {
  mode: "app",
  cache: {
    maxAge: 60,
    loaderMaxAge: 15,
  },
};
```

- `maxAge` is the response-cache lifetime in seconds.
- `loaderMaxAge` is the loader-data cache lifetime in seconds.
- A missing or zero value disables that cache.

The cache key includes the request path. Loader keys also include the route and
its parameters.

## Distributed cache

Core includes the cache contracts. For shared cache state across server
instances, use the optional Redis-compatible provider:

```bash
npm install @neutron-build/cache-redis ioredis
```

```ts
import { createServer } from "@neutron-build/core";
import { createRedisNeutronCacheStores } from "@neutron-build/cache-redis";

const cache = await createRedisNeutronCacheStores({
  url: process.env.DRAGONFLY_URL ?? process.env.REDIS_URL,
  keyPrefix: "my-app:",
});

await createServer({ cache });
```

The provider works with Redis or a compatible Dragonfly endpoint. It stores
app and loader entries separately and supports deleting entries by route path.

Do not cache personalized responses unless the cache policy and keying scheme
provide the required user isolation.
