A hard refresh reloads the page while telling the browser to ignore its cached copies of the page and the resources on it. On Windows and Linux it is Ctrl+F5 or Ctrl+Shift+R in Chrome, Edge and Firefox. On a Mac it is Cmd+Shift+R in Chrome, Edge and Firefox, and Option+Cmd+R in Safari after enabling the Develop menu. It does not clear cookies, it does not clear site data, and it cannot reach a cache that lives anywhere other than the browser, which is why a hard refresh after a deploy sometimes changes nothing at all.
The top results for this term are tables of keyboard shortcuts, and that is the right answer for most people asking. The reason a hosting company has a post on it is the second question, the one those tables do not answer: you deployed, you hard-refreshed, and the old version is still there. That is a caching problem in a layer the shortcut does not reach, and the second half of this post is about which layer.
Table of contents
- The shortcuts, by browser and operating system
- What a hard refresh clears, and what it does not
- When hard refresh does nothing: the four other caches
- Fixing it at the source so nobody has to hard refresh
- A note on testing deploys
- How this fits the rest of the stack
- FAQ
The shortcuts, by browser and operating system
All of these send the request with headers that instruct the browser to revalidate or bypass its own cache for the page and the assets it loads.
- Chrome and Edge on Windows or Linux: Ctrl+F5, or Ctrl+Shift+R. Both do the same thing.
- Chrome and Edge on Mac: Cmd+Shift+R. Holding Shift while clicking the reload button also works.
- Firefox on Windows or Linux: Ctrl+F5 or Ctrl+Shift+R. On Mac: Cmd+Shift+R.
- Safari on Mac: enable the Develop menu in Settings, Advanced, then Option+Cmd+R, or Option-click the reload button. Safari also has Develop, Empty Caches, which clears everything rather than just this page.
- Mobile: there is no hard-refresh gesture. Clear the site’s data in the browser settings, or open the page in a private tab, which starts with an empty cache.
Chrome and Edge have a third option that is stronger than either shortcut. With DevTools open, right-click the reload button and choose Empty Cache and Hard Reload. That evicts the cached entries for the page rather than just bypassing them for one request, and it is the one to use when you are testing a deploy.
What a hard refresh clears, and what it does not
A normal reload lets the browser reuse anything it has cached that has not expired. A hard refresh tells the browser to ignore the cache for the page and for the resources the page references directly: stylesheets, scripts, images. That is the whole of it.
It does not clear cookies, so you stay logged in. It does not clear localStorage, IndexedDB or session storage, so application state survives. It does not clear the HTTP cache for other pages on the site. And, importantly, it does not affect resources that the page loads later, after the initial render, such as scripts a framework fetches on demand, because those requests are made by JavaScript rather than by the reload. The cache miss post goes into what a cache actually stores and when it is consulted.
The one many people confuse it with is clearing the cache. Clearing the cache empties the browser’s store for every site. A hard refresh bypasses it for one page, once. If you find yourself doing a hard refresh every time you visit a site, the site has a caching bug, and the fix is on the server side, not in your keyboard.
When hard refresh does nothing: the four other caches
You deployed. The build log said success. You hard-refreshed and the old page is still there. The browser cache was never the problem; one of these was.
- A service worker. If the site registered one, it intercepts requests and can serve from its own cache regardless of how the page was reloaded. Hard refresh does bypass the service worker for the navigation request in Chrome, but the worker is still installed and will serve the next visit from its cache. Unregister it in DevTools, Application, Service Workers, or ship a worker update that clears its own caches.
- A CDN or edge cache. The request never reaches your origin; the edge answers from its copy, and the edge does not care what headers your browser sent. Purge the CDN, or version the file names so the URL changes with the content.
- A server-side cache. WordPress page caches, framework output caches, a reverse proxy cache in front of the app. The origin itself is serving stale HTML. The WordPress cache layers post lists four of these for one CMS alone.
- DNS. If the deploy moved the site to a new address, your machine may still be resolving the old one. That is not a page cache at all, and a hard refresh does not touch it; flushing the resolver cache does.
The way to tell which one is to fetch the page from outside the browser and look at the response headers:
curl -sI https://example.com/ | grep -iE 'cache|age|etag|last-modified|cf-|x-'
# Age: 5400 -> an intermediate cache has held it for 90 minutes
# x-cache: HIT -> a CDN answered, not the origin
# cache-control: max-age=31536000 -> the browser was told to keep it for a year
An Age header or a cache HIT means the freshness problem is upstream of the browser, and no shortcut fixes it.
Fixing it at the source so nobody has to hard refresh
Hard refresh is a developer’s tool. Visitors do not know it exists, so a site that needs one after every deploy is a site whose visitors see stale pages. The fix is to set cache headers so that the things that change are revalidated and the things that do not are cached hard.
- HTML: cache-control: no-cache, or a short max-age with must-revalidate. The page itself should always be checked.
- Assets with hashed file names, such as app.3f2a9c.js: cache-control: public, max-age=31536000, immutable. The name changes when the content does, so the cache never goes stale.
- Assets without hashes: short max-age, or add the hashes. Most build tools do this by default.
- A service worker, if you have one: version its cache name on every deploy and delete old caches on activate.
On a static site those headers are a configuration file, not server code. RunxBuild static sites take them from a headers file, and a build from the repository produces hashed asset names so the long max-age is safe. That combination means a deploy is visible on the next normal reload, for everyone, with no shortcut involved.
A note on testing deploys
When checking whether a deploy landed, do not trust your own browser at all. Use a private window, use curl, or use a different device. Your browser has a service worker, a warm cache, and a DNS entry from before the deploy, and any one of them will lie to you. The build log tells you the deploy happened; an independent request tells you it is being served. On a platform that keeps deploy history, the two should be checked together, and if the second disagrees with the first, one of the four caches above is the reason.
How this fits the rest of the stack
Hard refresh is the right answer for the person asking and the wrong answer for the site that keeps needing it. Cache headers, hashed file names and a CDN purge are the actual fix, and they are configuration rather than code. If you are deciding where a site should live so that this is handled, the RunxBuild hosting calculator shows the static hosting, the bandwidth and any backend service as separate line items. Set the headers once, and let the reload button do its job.
Useful related references:
- Clearing WordPress Cache: Four Layers, and the One You Forgot
- What Is a Cache Miss, and Why Your Hit Ratio Is Lower Than You Think
- Flush DNS Cache on macOS: The Command, and Why It Usually Is Not the Problem
- Response headers on RunxBuild
FAQ
What is a hard refresh?
A reload that tells the browser to ignore its cached copies of the page and the resources it references, and fetch them from the server again. It does not clear cookies, site data, or the cache for other pages, and it does not affect caches that live outside the browser, such as a CDN or a server-side page cache.
What is the shortcut for a hard refresh in Chrome?
Ctrl+F5 or Ctrl+Shift+R on Windows and Linux; Cmd+Shift+R on a Mac. With DevTools open, right-clicking the reload button offers Empty Cache and Hard Reload, which evicts the cached entries rather than bypassing them once.
How do I hard refresh in Safari on a Mac?
Enable the Develop menu under Settings, Advanced, then press Option+Cmd+R or Option-click the reload button. Develop, Empty Caches clears the cache for every site rather than just the current page.
What is the difference between a hard refresh and clearing the cache?
A hard refresh bypasses the cache for one page, once. Clearing the cache empties the browser’s stored copies for every site. Neither clears cookies unless you choose that separately. If a site needs a hard refresh every visit, its cache headers are wrong.
Why is a hard refresh not fixing my page?
Because the stale copy is not in your browser. A service worker, a CDN edge cache, a server-side page cache, or a stale DNS entry can all serve old content regardless of how you reload. Fetch the page with curl -I and look for an Age header or a cache HIT to find which layer is answering.