Cache and Update Test Guide
A reference for the DeskTest.net Cache and Update Test - the "a hard refresh fixes it" inspector. Explains what a service worker and Cache Storage are, why a page can keep showing an old version after you reload, how to read the verdict, and exactly how to force an update on Chrome, Edge, Firefox, and Safari.
Open the Cache and Update Test →
What does the Cache and Update Test check?
Two read-only probes that run automatically against the origin you open the tool on (here, desktest.net). No clicks during the run, no plugin, no network request.
- Service workers registered for this site. Calls
navigator.serviceWorker.getRegistrations()and reports each worker's scope, the state of its installing / waiting / active instances, and whether an updated worker is waiting to take over. It also checksnavigator.serviceWorker.controllerto see whether a worker is controlling this page, and reads the Navigation Timing entry to note whether the page arrived withtransferSize0 - the signature of content served from a cache or a worker rather than freshly over the network. - Cache Storage buckets and storage usage. Calls
window.caches.keys()to list the Cache Storage buckets present (and opens each read-only to count the responses inside), thennavigator.storage.estimate()for the quota and usage in MB and as a percentage.
Why a page keeps showing an old version
Modern web apps deliberately keep copies of their files on your machine so they load instantly and work offline. Three separate layers can hold an old copy:
- The HTTP cache. The browser's ordinary disk cache of files it downloaded. A normal reload can re-use it; a hard reload bypasses it. This is not part of the Service Worker or Cache Storage APIs and a page can be served from it with no worker at all.
- Cache Storage. A named, script-controlled store (the Cache API). A site's own JavaScript decides what goes in and when it is replaced. If the replacement logic is wrong or has not run, an old asset stays.
- A service worker. A background script that sits between the page and the network and can answer requests from Cache Storage before the network is ever consulted. This is the layer that most often causes "I deployed a fix an hour ago and users still see the old page." A service worker updates on its own schedule, and a freshly downloaded one waits until every tab for the site is closed before it takes over.
An honest limitation: the browser cannot always prove that a cached copy is out of date. It only knows a worker or cache is present and could serve old content. So this tool reports presence and state, and always gives you the action - a hard reload or clearing site data - that forces fresh content regardless.
When should I run this?
- "I deployed a fix but the change is not showing." Run it on the affected site to see whether a service worker or Cache Storage is intercepting requests, and whether an update is stuck waiting.
- A user reports a bug you cannot reproduce. Often they are pinned to an old build by a stale worker. Have them open
/cache-test/on the app, read the verdict, and follow the force-update steps. - After a big release of a progressive web app (PWA). Confirm the new service worker actually activated rather than sitting in the waiting state on real machines.
- Intermittent breakage on one workstation. If storage is near quota, the browser may be evicting cached data unpredictably; this tool flags that pressure.
Reading the results
Each step gets a status badge: Pending, Running, Pass, or Warn. There is no "Fail" - the presence of a worker or cache is not a fault, just something that can serve stale content, so it is surfaced as a warn with an action.
The verdict panel at the top gives a one-line title, the likely cause, and the recommended next step. Its priority order is: a waiting service worker update (most actionable), then an active service worker, then storage pressure, then plain Cache Storage presence, then a clean bill of health.
| Diagnosis | What it means | What to do |
|---|---|---|
sw-update-waiting | A newer worker is installed but the old one still controls the page. | Close every tab for the site and re-open, or click skipWaiting in DevTools. |
sw-active | An active worker is registered and can answer from its cache. | Hard reload; if needed, Update the worker or Clear site data. |
storage-pressure | Usage is at or above 80% of the origin's quota; eviction is likely. | Clear this site's data to reset it cleanly. |
caches-present | No worker, but Cache Storage buckets exist that could hold an old copy. | Hard reload; Clear site data to empty the buckets. |
no-sw / storage-light | No worker and light cache - nothing here should be stale. | If content still looks old, it is the HTTP cache or the server. Hard reload once, then check the server. |
Copy Diagnostic Report writes a plain-text summary to the clipboard: origin, secure context, how the page arrived, every registration with its scope and states, the cache buckets and their response counts, and the storage estimate. Paste it into a ticket. View diagnostic report shows the same text inline first.
How to force an update
1. Hard reload (try this first)
A hard reload asks the browser to bypass the HTTP cache for the reload:
- Windows / Linux: Ctrl+F5, or Ctrl+Shift+R.
- Mac: Cmd+Shift+R.
A hard reload does not reliably bypass a service worker on its own, which is why the next steps exist.
2. Update or unregister the service worker (DevTools)
Open DevTools with F12 (Chrome, Edge) and go to the Application tab, then Service Workers:
- Click Update to re-fetch the worker script, or skipWaiting to let a waiting worker take over immediately, then reload.
- Tick Update on reload while you are actively testing so every reload re-installs the worker.
- Click Unregister to remove the worker entirely; the next load starts clean.
In Firefox the equivalent lives at about:debugging#/runtime/this-firefox under Service Workers, with an Unregister button. Safari exposes service workers in the Develop menu (Develop → Service Workers).
3. Clear site data (the reliable reset)
This unregisters workers and empties Cache Storage, cookies, and local storage for the one origin, without touching other sites:
- Chrome / Edge: DevTools → Application → Storage → Clear site data. Or click the padlock in the address bar → Site settings → Delete data.
- Firefox: padlock → Clear cookies and site data, or Settings → Privacy & Security → Cookies and Site Data → Manage Data.
- Safari: Settings → Privacy → Manage Website Data, find the host, and Remove.
For IT admins and developers
For a stuck worker on a user's machine, the fastest reliable fix over the phone is Clear site data for that one origin, then reload. It never touches other sites and always produces a clean state. Closing every tab of the site also lets a waiting worker activate, but users rarely have just one tab.
If you ship a PWA, the waiting-worker problem is a deployment concern, not a user error. Decide deliberately between letting the new worker wait (users get the update on their next full restart, no interruption mid-session) and calling self.skipWaiting() plus clients.claim() to take over immediately (instant update, but risks a version mismatch between an already-open page and freshly cached assets). Pair skipWaiting with a "new version available - reload" prompt rather than swapping assets silently under a live page.
Cache-busting still matters. Content-hashed filenames (app.9f3c2.js) plus a correct Cache-Control policy - long max-age for hashed assets, no-cache for the HTML entry point and the service worker script itself - prevent most stale-content tickets before a worker is even involved. Browsers additionally cap how long a service worker script is cached and re-fetch it on navigation, but a wrong Cache-Control on the worker file can still delay updates; serve it with no-cache.
Managed fleets: Chrome and Edge expose policies to clear browsing data on exit and to control caching, but there is no policy that surgically clears one site's service worker. For a fleet-wide bad-worker incident, the practical levers are a server-side kill switch (ship a no-op worker that unregisters itself) or guiding users through Clear site data.
Behind the scenes
Step 1 reads navigator.serviceWorker.getRegistrations(), which returns every registration scoped under this origin. For each it inspects the installing, waiting, and active slots; a non-null waiting worker in the installed state is the "update waiting" signal. navigator.serviceWorker.controller tells whether the current page is being controlled by a worker at all - a page loaded with a hard reload is deliberately uncontrolled even when a worker exists, which the tool accounts for. The Navigation Timing entry (performance.getEntriesByType('navigation')[0]) contributes deliveryType (Chromium 106+) and transferSize; a transferSize of 0 alongside a real body means the bytes did not cross the network on this navigation.
Step 2 calls window.caches.keys() for the bucket names, then opens each bucket read-only and calls cache.keys() to count entries (capped so a site with hundreds of buckets cannot hang the page). navigator.storage.estimate() returns usage and quota; the quota is the browser's per-origin budget, not your disk size, and both are deliberately coarse to avoid fingerprinting. navigator.storage.persisted() reports whether the origin has been granted persistent (non-evictable) storage.
Both navigator.serviceWorker and window.caches require a secure context; over plain http:// they are absent, and the tool reports that honestly rather than inventing a result. Nothing leaves the browser: there are no network requests, and the tool mutates no worker, cache, or storage. View source to verify.
Related
- Cache and Update Test - the diagnostic itself
- Browser Test Guide - secure context, storage availability, and web API support
- Network Test Guide - the equivalent for connectivity and DNS
- About DeskTest.net
- Help: getting started
- DeskTest.net home
Elsewhere on the web:
- MDN: Service Worker API - how workers install, wait, and activate.
- web.dev: The service worker lifecycle - the definitive explanation of the waiting/skipWaiting behavior.