Skip to content
A mailroom conveyor separates one personalised mail sleeve from a stream of general mail, showing the risk of sending private items through the wrong route.

Should Logged-In Pages Be Cached? What to Set on Private Responses

Avidni Editorial Team / Care5 min read.

Personalised pages can be cached safely, but only with the right scope. This guide separates browser cache from shared cache, then shows when private, no-cache, or no-store fits.

A customer opens a portal on a shared laptop, signs out, and the next person still sees account data because the page was cached in the wrong place. The opposite mistake is more common than teams like to admit: they disable caching across the whole application to avoid that risk, then make public pages slower than they need to be. The problem is not caching itself. It is letting the wrong response live in the wrong cache, for longer than the response was meant to stay there.

That decision starts with the HTTP cache model described in MDN's HTTP caching guide: a cache stores a response and reuses it later when the rules allow. web.dev's HTTP cache article makes the same split from an operational angle. Browser caches belong to one client, while shared caches can sit in CDNs, proxies, and other intermediaries. Once a response varies by session, role, branch, or account, the wrong cache scope can turn convenience into leakage. Cache control therefore belongs in the same conversation as login state, logout behaviour, and access checks.

Keep the scopes separate. A browser cache is private to one browser profile, so a personalised dashboard may be acceptable there if the content should reappear on that same device. A shared cache is different because one stored response can serve more than one client. If the page includes balances, tickets, order history, branch data, or support notes, the question is not whether the user is signed in. It is whether another user could ever receive that stored response. On a desk shared by shift workers or at a branch kiosk, that distinction is not theoretical.

MDN is clear that a response containing personalised content may stay in a private cache, and that placing it in a non-private cache can expose it to other users. It also warns that a cookie alone does not make the response private. That matters because many applications send cookies on nearly every authenticated request. A session cookie tells you the request is part of a logged-in flow, but it does not tell you whether the response body contains user-specific content, public account metadata, or a page that should never be retained. The header must match the content, not the presence of a cookie.

The next split is between reuse and storage. `Cache-Control: no-cache` still allows storage, but requires revalidation before reuse. `Cache-Control: no-store` goes further and tells caches not to store the response at all. That difference is easy to blur in review, yet it matters operationally. If the response can safely sit in the user's browser but should always be checked before reuse, no-cache is the narrower fit. If the response is sensitive, unpredictable, or too risky to leave anywhere at rest, no-store is the stronger choice. web.dev's guidance on HTTP cache behaviour matches that same division.

A useful working rule is therefore simple. Public, versioned assets can be cacheable by any cache. Personalised pages that may stay in the user's browser cache should usually be private, with no-cache when you want the browser to validate before reuse. Sensitive or unpredictable responses belong in no-store. That split lets teams keep public pages fast while narrowing the blast radius of personal data. It also prevents the more expensive mistake: using no-store everywhere and then discovering that ordinary marketing pages, documentation, and other public assets no longer benefit from caching.

Cache-Control choices that fit the response

Decision table for public, personalised, and sensitive responses
Response typeHeader choiceOperational effectWhen to use
Public, versioned assetsCache-Control: public, max-age=31536000Any cache may store the response. Versioned URLs should change when the file changes.Static assets such as hashed CSS, JavaScript, images, and other user-agnostic files.
Personalised pages that may live only in the user's browser cacheCache-Control: private, no-cacheThe browser may retain the response, shared caches must not, and the browser revalidates before reuse.Logged-in pages where a cached copy is acceptable on the same device, but not in a shared cache.
Sensitive or unpredictable responsesCache-Control: no-storeNothing should be stored in any cache.Secrets, one-time views, highly sensitive account pages, or responses that should leave no cached copy behind.

Validators belong in the conversation because they turn browser-only caching into a revalidation path rather than a blind reuse path. If you use `no-cache` with `ETag` or `Last-Modified`, the browser can keep a local copy and ask the server whether it is still current. An unchanged response can return `304 Not Modified`, which is the efficient outcome for many dashboards and portal views. But this is not the same as a guarantee of a fresh network request on every navigation. Some browser history paths may restore a page from back-forward cache instead, so teams should treat Back button behaviour as its own case and test it directly.

How to tell the setting is wrong

Diagnostic path for private and authenticated pages
SymptomCheckExpected observationInterpretation and next action
A signed-in user can see another user's personalised content on a shared device or through an intermediary cache.Inspect the response headers and confirm whether the page is eligible for shared reuse instead of being limited to a private cache.The response lacks private or no-store, so it can be reused beyond one client.The response is being treated as cacheable in the wrong scope. Restrict it to private, or move to no-store if storage itself is unacceptable.
Pressing Back shows an older account page without a fresh server check.Look for no-cache or max-age=0, then remember that history navigation can also use the browser back-forward cache, often called bfcache.The page returns as a snapshot or is reused without a visible network round-trip.Do not assume no-cache forces a fresh fetch in every navigation path. Treat bfcache as a separate browser behaviour and test it directly.
A personalised page still revalidates efficiently and does not leak across users.Confirm an ETag or Last-Modified header is present with a revalidation directive such as no-cache.Unchanged responses return 304 Not Modified and the browser keeps its local copy.This is the normal browser-only caching path. It is efficient, but only suitable when the page may remain in the user's own cache.
  1. Inspect Cache-Control on every response type and confirm the directive matches the page's purpose. Public assets should be public and versioned. Personalised pages should be private, with no-cache only where revalidation is required. Highly sensitive responses should be no-store.
  2. Test the page in a shared browser profile or on a second device after logout and confirm that user-specific content does not appear from a shared cache. This matters on branch desktops, reception kiosks, warehouse terminals, and support desks that multiple people touch.
  3. Verify the validator path when you use no-cache. If the response should stay in the user's browser cache, check that unchanged content comes back with `304 Not Modified` rather than a full re-download.
  4. Navigate with the Back button and confirm whether the browser restores a snapshot from bfcache instead of making a network request. If that path reveals sensitive data, no-cache is not enough on its own.
  5. Confirm that cache headers do not replace access control. The same operational split discussed in [Authentication Is Not Authorization: Why Signed-In Users Can Still Be Blocked](/blog/authentication-not-authorization-signed-in-users-blocked) still applies: a response can be authenticated and still be cached incorrectly, or blocked correctly and still need the right cache policy.

Two limits deserve emphasis. First, private does not mean confidential in every sense. It limits sharing with other clients, but it does not erase data from the user's own device, from screenshots, or from browser history mechanisms. Second, no-store is not a substitute for application logic. It reduces retention, but it does not fix broken authorisation, weak logout flows, or pages that expose too much data in the first place. If the response is too sensitive to risk at all, the answer is usually a combination of no-store, strict access checks, and a smaller response surface. That same split should sit alongside Before a Kenyan Portal Goes Live: 14 Privacy Questions when teams review portals, dashboards, checkout states, and support consoles.

Build the website or system your next stage needs.

Strategy, Delivery and Ownership in one accountable process.

Bring the brief, the challenge or simply the outcome you need. Avidni will shape it into a clear delivery plan for a business website, e-commerce store, client portal or automated workflow. You will know what is being built, who owns each decision and what happens after launch, with ongoing care available where it adds real value.

Start a Project