Glossary

Definition

activate event (service worker)

Short definition

The activate event fires after a service worker moves from "installed" to "activating", typically once the old worker's clients have all closed or skipWaiting() was called. Handlers commonly use it to clean up outdated Cache Storage entries left behind by earlier versions of the app shell.

Reviewed July 26, 2026

A typical cleanup handler: self.addEventListener("activate", (event) => { event.waitUntil(caches.keys().then((keys) => Promise.all(keys.filter((k) => k !== "shell-v2").map((k) => caches.delete(k))))); });, which removes any cache whose name does not match the current version tag.

Deleting old caches in install instead of activate is unsafe, because the previous worker may still be serving pages from those caches until it is fully replaced.

Calling event.waitUntil(clients.claim()) inside activate lets the new worker start controlling already-open pages immediately, rather than waiting for the next navigation — this is the standard pairing with skipWaiting() for apps that want instant updates.

Errors thrown synchronously in the activate handler, or a rejected waitUntil promise, leave the worker in a failed state and it will be discarded on the next registration attempt.

Related terms
install event (service worker)
The install event fires on the ServiceWorkerGlobalScope the first time a browser registers a new or updated service worker script. Handlers typically call event.waitUntil(caches.open(...).then(cache => cache.addAll([...]))) to pre-cache the app shell before the worker is allowed to move to the "installed" state.
clients.claim()
self.clients.claim() is called inside the activate event of a service worker to make it start controlling every open page on the origin right away, rather than the default behaviour where a page keeps being controlled by whatever worker was active when it first loaded until the next navigation.
Cache Storage API
The Cache Storage API, exposed as the global caches object, lets a service worker (or page) store Request/Response pairs in named caches, e.g. caches.open("shell-v1").then((cache) => cache.put("/logo.png", response)). Unlike the HTTP cache, it is fully scriptable, has no automatic eviction schedule tied to headers, and persists until explicitly deleted or the storage quota is exceeded.
fetch event (service worker)
The fetch event fires in the service worker for every navigation, script, image or XHR request originating from a page it controls. Calling event.respondWith(promise) lets the worker substitute its own Response, most commonly by checking the Cache Storage API first and falling back to fetch() from the network.
waiting state (service worker)
A service worker enters the waiting state after install succeeds but before it can activate, because the browser only replaces an active worker once every page it currently controls has been closed or navigated away from. It stays here indefinitely until those pages close or the code forces the transition with skipWaiting().
skipWaiting()
self.skipWaiting() is called inside a service worker's install (or activate) handler to skip the normal waiting state and activate immediately, even while older pages controlled by a previous worker are still open. It is usually paired with clients.claim() so the new worker also starts controlling those pages right away.