Shaduf.Research preview
HTTP Cache Field Guide/Service-worker updates and stale client assets

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.

Documentation-only; no live result. No target application, origin, browser/version, worker, permission to test, or analytics was supplied. No request was made and no browser check ran. Every test scenario in this report is expected and unexecuted; there are no observed deployment outcomes.

The short answer

  1. 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.
  2. 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.
  3. clients.claim() is separate from skipWaiting(): an active worker can take control of eligible matching clients not already using that registration. Neither call replaces page code or clears caches.
  4. 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.

Service-worker update, activation, and asset retention A changed worker is discovered and installed. An install failure leaves the current worker active. A successful worker normally waits for old clients to drain, or skipWaiting can bypass that wait. Activation changes the controller for clients already using the registration but not their in-memory document. clients.claim is a separate active-worker action for eligible matching clients not already using the registration. Old Cache Storage entries remain until application cleanup under a compatibility policy. Update check changed scriptfound Install v2 install work can failor succeed Waiting normal path waits forold clients to drain Activate v2 old controlled clientschange controller Reload? page codestill old Install fails v1 remains active optional skipWaiting() bypasses the drain wait Separate option: clients.claim() active worker may take eligible matchingclients not already using its registration Cache Storage is not auto-cleared keep old entries until the compatibilitypolicy permits app-directed cleanup Activation changes control, not open-page code.App policy sets when old cache entries can retire.
The normal wait, 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

StageSpecified lifecycle pointWhat can still be oldWhat a deploy does not guarantee
Update checkThe 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.
InstallingA 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.
WaitingAfter 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.
ActivationNormal 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 cleanupAn 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

ChoiceEffectCompatibility concern
NeitherThe 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.
BothAllows 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-v2 has no automatic connection to a worker version. Worker code must populate it and route requests to it.
  • Do not delete app-shell-v1 just because the v2 activate handler 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

  1. Publish v2 fingerprinted assets first. Keep v1 assets available through the v1 compatibility window.
  2. 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.
  3. 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.
  4. Let old pages drain by default. Detect a waiting candidate and present an update notice. A notice is app UI, not a platform requirement.
  5. 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. Add clients.claim() only when the application intends to adopt otherwise uncontrolled pages.
  6. 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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
Do not use a single observation as a full attribution. A “from service worker” label, a cache entry in DevTools, an active registration, or a missing origin hit does not establish every other layer's behavior.

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.

ScenarioExpected result if conditions holdCaptureLimit
Leave a v1 tab open; publish v2 and perform an update checkA 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 remainsThe 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 pageExpected 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 retirementOutcomes 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

LabelUse in this reportBoundary
NormativeThe 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 guidanceMDN 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/unexecutedEach synthetic row predicts a result for an authorized test with stated conditions.No row is an observed outcome.
ObservedNo 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.
UnknownActual 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

Developer and browser guidance

Search published pools, pages, reports, and evidence.