# Service worker cache versioned and cleaned on deploy

- **Pattern:** `ab-002028` (`performance-deep-dive.caching-cdn.service-worker-cache-versioning`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002028
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002028)

## Why it matters

A service worker that caches resources without versioning accumulates stale content indefinitely. When you ship a bug fix or critical update, users with a running service worker continue receiving the broken cached version — potentially for weeks, until they manually clear their cache or the browser evicts it. The cache name must change on each deploy, and the `activate` event must delete old caches. ISO 25010:2011 time-behaviour flags cache effectiveness; the operational risk is users being stuck on outdated or broken application versions with no server-side way to force an update.

## Severity rationale

High because unversioned service worker caches leave users running stale application code after deploys, with no server-side mechanism to force a refresh without manual cache clearing.

## Remediation

Include a version string or content hash in every cache name and delete all prior cache versions in the service worker's `activate` event.

```js
// public/service-worker.js
const CACHE_NAME = 'app-cache-v2.1.0'  // bump on each deploy

self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches.keys().then((keys) =>
      Promise.all(
        keys.filter((key) => key !== CACHE_NAME).map((key) => caches.delete(key))
      )
    )
  )
})
```

## Detection

- **ID:** `service-worker-cache-versioning`
- **Severity:** `high`
- **What to look for:** Count all service worker files. Enumerate cache versioning strategies: version strings, content hashes in cache names, and cleanup handlers. Check for a service worker file (`public/service-worker.js`, `app/service-worker.js`, or equivalent). Look for cache versioning (e.g., a version string or hash in the cache name). Verify that on new deploys, the cache version changes and old caches are cleaned up via `caches.delete()`.
- **Pass criteria:** A service worker is implemented. Cache keys include a version string or hash. The service worker deletes old caches on activation (in the `activate` event). New deploys update the cache version, triggering cleanup. At least 1 version string or hash-based cache name must be present.
- **Fail criteria:** No service worker implemented, or the service worker does not version caches or clean up old caches.
- **Skip (N/A) when:** The project is a static site with no dynamic content or service worker needs.

- **Cross-reference:** For broader cache-busting strategy, see the `cache-busting-documented` check.
- **Detail on fail:** `"No service worker found in project"` or `"Service worker caches with fixed name 'app-cache' — old cache never deleted, disk usage grows with each deploy"`
- **Remediation:** Implement a service worker with versioned caches that cleans up old versions on activation.

  ```js
  // public/service-worker.js — versioned cache with cleanup
  const CACHE_VERSION = 'v2.0.0'
  self.addEventListener('activate', (e) => e.waitUntil(caches.keys().then(keys => Promise.all(keys.filter(k => k !== CACHE_VERSION).map(k => caches.delete(k))))))
  ```

## External references

- iso-25010 time-behaviour

Taxons: performance

HTML version: https://auditbuffet.com/patterns/ab-002028
