---
title: "Persistent Storage"
description: "Configure persistent storage for build assets across deployments."
canonical_url: "https://nuxtseo.com/docs/skew-protection/guides/storage-configuration"
last_updated: "2026-09-24T04:31:20.175Z"
---

Nuxt Skew Protection needs persistent storage to preserve previous build assets across deployments.

The default storage path is `node_modules/.cache/nuxt-seo/skew-protection`. If your CI pipeline clears this directory, restore it before each build.

## Retention Periods

Set retention limits with [`retentionDays`](/docs/skew-protection/api/config#retentiondays-number) and [`maxNumberOfVersions`](/docs/skew-protection/api/config#maxnumberofversions-number). The defaults keep up to 10 versions for 30 days.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  skewProtection: {
    // Keep versions for 45 days
    retentionDays: 45,
    // Keep maximum 15 versions
    maxNumberOfVersions: 15
  }
})
```

Cleanup happens **during build**, removing:

- Versions older than `retentionDays`
- Oldest versions beyond `maxNumberOfVersions`

## GitHub Actions

The default filesystem storage works with GitHub Actions caching to persist build assets between deployments
using the `actions/cache` GitHub Action.

::warning
The cache key must be unique per deployment, otherwise `actions/cache` won't save new assets (it only saves on cache miss).
::

```yaml [your-github-workflow.yml]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # Install...
      - name: Cache for Nuxt SEO
        uses: actions/cache@v4
        with:
          path: node_modules/.cache/nuxt-seo
          key: nuxt-skew-${{ github.sha }}
          restore-keys: |
            nuxt-skew-
      # Build, etc..
```

The `restore-keys` fallback restores previous assets. A unique `github.sha` key lets the cache save new assets after each build.

## Cloudflare

If you have your deployments running through [Cloudflare](https://cloudflare.com) then the `node_modules` folder should automatically persist between deployments, so you do not need any additional configuration.

If you're deploying to Cloudflare using your own CI pipeline, you can use Cloudflare KV storage to persist build assets instead. See the dedicated [Cloudflare Deployment](/docs/skew-protection/providers/cloudflare) guide which covers storage configuration in detail.

## Redis

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  skewProtection: {
    storage: {
      driver: 'redis',
      host: process.env.REDIS_HOST || 'localhost',
      port: Number(process.env.REDIS_PORT) || 6379,
      password: process.env.REDIS_PASSWORD,
      db: 0,
      base: 'skew-protection'
    }
  }
})
```

## Upstash Redis

For serverless deployments like [Netlify](https://netlify.com) or [Vercel](https://vercel.com), [Upstash](https://upstash.com/) provides a Redis-compatible database with an HTTP API.

Install the Upstash [Redis](https://redis.io) client:

```bash [Terminal]
npx nypm add @upstash/redis
```

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  skewProtection: {
    storage: {
      driver: 'upstash',
      url: process.env.UPSTASH_REDIS_REST_URL,
      token: process.env.UPSTASH_REDIS_REST_TOKEN,
      base: 'skew-protection'
    }
  }
})
```

You can find your REST URL and token in the [Upstash Console](https://console.upstash.com/) after creating a database.

## CDN Usage

If your CDN already keeps `/_nuxt/**` assets available across deployments, you can disable asset bundling with [`bundleAssets`](/docs/skew-protection/api/config#bundleassets-boolean).

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  skewProtection: {
    // Disable persistent storage
    bundleAssets: false
  }
})
```

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
