Dated report · service-worker updates · 28 Sep 2026
Service-worker updates and stale client assets
A worker update changes a registration through specified lifecycle steps. It does not rewrite an open document or automatically remove Cache Storage entries.
The short answer
- A deployment is not a notification to every browser. A changed worker must be found by an update job and install successfully. If install fails, the prior active worker remains active. A candidate normally waits until no clients are using the old registration and the old worker has no pending events. See the specified update, install, and activation algorithms.
skipWaiting()asks a waiting worker to bypass the normal client-drain wait. During activation, clients already using the registration change to the new active worker and receive controller-change notification. The existing document and JavaScript remain in memory until an application reloads or navigates it.clients.claim()is separate fromskipWaiting(): an active worker can take control of eligible matching clients not already using that registration. Neither call replaces page code or clears caches.- Cache Storage is a script-managed store separate from the browser HTTP cache. Updating or activating a worker does not automatically change or delete its named caches. The application controls cache names, routing, and cleanup.
The Service Workers document cited here is a Candidate Recommendation Draft (CRD), not a W3C Recommendation. Its individual algorithms specify the described transitions; they do not prove that a particular deployment followed them.
skipWaiting(), and clients.claim() are different transitions. An application decides when an open page reloads and when old cache entries can be retired.What can remain from the old release
| Stage | Specified lifecycle point | What can still be old | What a deploy does not guarantee |
|---|---|---|---|
| Update check | The user agent runs an update job and compares worker script resources. Soft update requests can be rate-limited. | The prior worker remains active until a candidate activates. An open document retains its loaded code and asset URLs. | Immediate checking, an update for every browser, or refetching each page asset. updateViaCache concerns the HTTP cache for worker scripts/imports; it does not clear Cache Storage. |
| Installing | A changed candidate enters installing. Install work can use waitUntil(); rejected setup makes the candidate redundant. | The prior active worker remains active after a failed candidate install. An old page can later request its old lazy-loaded URL. | That a downloaded candidate has become active or that all required cache entries were populated. |
| Waiting | After successful install, a candidate with an active predecessor normally waits until clients using the registration unload and old-worker pending events settle. | The old active worker can continue handling in-scope requests. The open document and its asset manifest stay old. | Activation just because the deployment completed. Long-lived clients may extend the wait. |
| Activation | Normal activation follows the drain condition. skipWaiting() requests activation without that normal wait. The activation algorithm switches clients already using the registration to the new active worker and queues controller-change notification. | When a new worker takes control, an old page can remain in memory while later requests go through the new worker. Its next old-URL request may need the old entry or old server file. | A reload, rewrite of loaded JavaScript, cache deletion, or compatibility between old page code and new fetch logic. |
| Claim and cache cleanup | An active worker's clients.claim() separately claims eligible matching clients not using its registration. Cache Storage methods let scripts manage named caches. | Old cache entries and fingerprinted files can remain. Storage pressure can remove best-effort stored data; a cache miss must be handled. | That claim() clears a cache, or that an earlier Cache Storage entry will remain indefinitely. |
skipWaiting() and clients.claim() are separate choices
| Choice | Effect | Compatibility concern |
|---|---|---|
| Neither | The candidate follows the normal wait for clients of the old registration to unload. A first-install page may remain uncontrolled until navigation. | Preserves the old page/worker pairing while those pages remain, but can delay update adoption. |
skipWaiting() | Requests that a successfully installed waiting worker bypass the normal drain wait. Activation switches current clients using that registration to the new active worker and notifies them. | An old document can continue running while the new worker handles its requests. Use only if old page versions remain supported or the app coordinates safe state and reload. |
clients.claim() | An active worker can take control of eligible matching clients not already using its registration. MDN notes this can include pages loaded over the network or possibly through another worker. | It broadens which pages receive that worker's fetch handling. It is not needed for ordinary navigations after activation and does not reload the page. |
| Both | Allows faster activation and can also take over additional eligible matching clients. | Largest compatibility surface. Treat this as an explicit app update flow, not a default compatibility assumption. |
The Activate and claim() algorithms define platform state changes. The application must decide whether running page code can safely continue after a controller change. See the Service Workers CRD algorithms and MDN claim guidance.
Keep worker caches and asset files compatible
The Service Workers specification describes named Cache API objects as script-managed and isolated from the browser HTTP cache. Calls such as open(), keys(), and delete() let the application manage them; a worker update does not automatically rewrite their entries. The WHATWG Storage Standard classifies Cache API data as local storage and says user agents under storage pressure should clear best-effort local-storage buckets.
- A name such as
app-shell-v2has no automatic connection to a worker version. Worker code must populate it and route requests to it. - Do not delete
app-shell-v1just because the v2activatehandler ran. An old page can request a v1 lazy chunk later. - Publish new fingerprinted paths without overwriting old bytes. Keep the old URLs available for the supported old-client and rollback window.
- Give mutable HTML a deliberate online revalidation and offline fallback policy. Ensure referenced files exist before publishing HTML that names them.
- Delete only caches owned by the application, under a documented compatibility rule. If the application cannot establish that no supported old page can need an entry, retain it or design for compatibility.
- Handle cache misses even when an entry was previously present; best-effort storage can be removed under storage pressure.
These are application/deployment recommendations. The platform does not set an old-cache retention period. A browser HTTP Cache-Control directive does not clear script-managed Cache Storage or update a running document.
Conservative rollout
- Publish v2 fingerprinted assets first. Keep v1 assets available through the v1 compatibility window.
- Install into a v2 cache. Use an explicit versioned cache and install lifetime work. Do not delete v1. Let required setup fail rather than activating an incomplete shell.
- Deploy worker and mutable HTML. Route v2 requests through an explicit v2 policy. Revalidate mutable HTML online and use a cached fallback only when offline behavior is intended.
- Let old pages drain by default. Detect a waiting candidate and present an update notice. A notice is app UI, not a platform requirement.
- Offer activation at a safe boundary. Save user work or reach an app-defined idle point, then offer a reload. A single tab's
skipWaiting()request can activate the worker for other controlled v1 tabs too. Do not use forced activation unless compatibility or coordination is explicit. Addclients.claim()only when the application intends to adopt otherwise uncontrolled pages. - Retire by policy. Keep old cache entries and server files while supported old pages or rollback paths may need them. Do not treat a point-in-time client list as proof that no old version can request an asset.
The right compatibility contract and retention window are unknown here: this job supplied no application versions, build manifest, active client inventory, or deployment policy.
Diagnose old content without mixing layers
- Record page and registration state. Capture the page build marker, registration scope, installing/waiting/active script URLs and states, and page controller script URL. Record both worker and page build markers.
- Ask whether a request occurred. Capture the exact URL/hash, initiator, response body marker, and whether history/back-forward restoration returned a document instead of a new navigation.
- Record the worker's branch. Log the URL, worker version, cache name and match/miss, and whether its handler returned the cache result or delegated to
fetch(). Delegation shows the worker's branch, not origin contact. - Continue to named downstream evidence. Preserve response timing, headers and marker. Correlate with a named intermediary record and origin counter/log when available; browser HTTP cache and downstream proxies remain separate possible layers.
For the generic named-hop sequence, continue with Locating the serving layer and the deployment and incident runbook. For ordinary HTTP freshness and stale-response boundaries, see When stale HTTP content is allowed.
Expected synthetic checks — not executed
Run only with an owner-approved synthetic app/origin, selected browser/version, v1/v2 markers, safe requests, and permission. No such setup was provided. These are expected outcomes under the listed conditions, not measurements.
| Scenario | Expected result if conditions hold | Capture | Limit |
|---|---|---|---|
| Leave a v1 tab open; publish v2 and perform an update check | A changed candidate can install and remain waiting while v1 clients use the registration. The page's build marker remains v1. Deployment alone does not guarantee that a check has run. | Browser/version; check trigger; updatefound; installing/waiting/active states and URLs; controller; page marker; worker marker. | Does not establish check timing or client state for other browsers/users. |
| Navigate in scope while v2 waits and a v1 client remains | The registration's v1 worker remains active; expected navigation handling uses the current active worker, subject to actual routing. | New page marker/controller; registration states; navigation response; worker match/fallback/delegate trace. | Worker delegation does not prove origin contact. |
Let all known test clients unload without calling skipWaiting() | The candidate becomes eligible to activate when the drain and pending-event conditions are met. Later navigation can use v2. | Test client inventory, state transitions, timestamps, activation log, cache names, next navigation marker. | Cannot prove global client drain, future old requests, or production compatibility. |
Deliberately call skipWaiting() with v1 open; separately call clients.claim() for an uncontrolled matching page | Expected activation can change the current controller while the v1 document marker stays v1 until reload. Claim can take over additional eligible matching clients. | Update message, worker marker, controllerchange, page marker before/after, subsequent exact asset URL and response marker, state-save result. | A controller change alone does not prove that page code or user work is safe. |
| Request v1 and v2 fingerprinted assets online/offline before and after declared retirement | Outcomes depend on explicit worker cache/fetch routing and server retention. After app-directed deletion, an old URL may miss; offline fallback may fail. | Exact hash, page/worker markers, cache names/keys, match result, response marker/status, network state, correlated origin record. | Cannot determine that no other supported old version can request v1 or set a universal retention period. |
Claim labels and unknowns
| Label | Use in this report | Boundary |
|---|---|---|
| Normative | The Service Workers CRD specifies registration slots, install failure, waiting and activation conditions, skipWaiting(), activation controller changes, clients.claim(), event lifetime, and named Cache API management. | The cited text is a Candidate Recommendation Draft; it is not proof of a particular browser/app result. The spec's high-level §2.5 “Control and Use” section is non-normative and points to HTML for control behavior; this report relies on the individual specified algorithms. |
| Browser guidance | MDN describes lifecycle use and practical update triggers; Chrome DevTools documentation describes Chrome-specific worker and Cache Storage inspection. | Not normative timing, a cross-browser inspection guarantee, or a measurement of this pool's application. |
| Expected/unexecuted | Each synthetic row predicts a result for an authorized test with stated conditions. | No row is an observed outcome. |
| Observed | No service-worker state, client count, cache key, request/response, body, activation, controller-change, or deployment symptom was observed in this run. | No browser or origin test was supplied or performed. |
| Unknown | Actual update timing, worker bytes and HTTP-cache response, install result, waiting clients, app compatibility, cache/fetch policy, storage state, old asset retention, and safe retirement window. | Requires the target application, browser/version, permission, deployment records, version markers, and an authorized test. |
Service Worker update checks can be frequency-limited; MDN's common triggers are browser-facing guidance, not a deploy-to-check or activation SLA. updateViaCache controls HTTP-cache use for worker script update checks/imports; it does not clear the Cache API.
Sources and audit window
Sources were checked in one web-research session, 28 Sep 2026 from to . The research tool did not expose separate response timestamps; no per-page time is inferred.
Primary standards
- W3C Service Workers and Cache API, Candidate Recommendation Draft, 17 Sep 2026: registrations, update/install/activate/try-activate algorithms,
skipWaiting(),clients.claim(),waitUntil(), and Cache API. - WHATWG Storage Standard, §§4.1, 4.5 and 7.1: storage buckets, Cache API storage, and storage pressure.
- WHATWG Fetch Standard, §§4.4 and 4.6: fetch layers and HTTP-network-or-cache fetch; a worker's delegated fetch is not proof of a named origin hop.
- WHATWG HTML Living Standard: document and navigation lifecycle context. The Service Workers CRD notes that its §2.5 high-level control/use discussion is non-normative and refers control behavior to HTML.
Developer and browser guidance
- MDN: Service Worker API and Using Service Workers: lifecycle overview and practical update guidance. Not normative.
- MDN:
skipWaiting(), MDN:Clients.claim(), and MDN:updateViaCache: API descriptions and developer-facing consequences. - Chrome DevTools: Debug Progressive Web Apps: Chrome-only inspection and update controls; changing those controls changes the experiment.