How to cache a site that changes constantly
How to get the benefits of caching on a site that has logins, carts or content updating constantly.
Blanket page caching assumes a page looks the same for everyone and stays the same until you next publish something. Plenty of real sites break both assumptions at once: a logged-in area is different for every visitor, a cart is different for every session, and a page showing live stock levels or comments changes more often than a simple cache timer can keep up with. None of that means caching is off the table — it means it has to be applied selectively rather than uniformly.
Work out what actually needs to be personal
The first step is not a technical setting — it is deciding, page by page, which parts of the site genuinely differ per visitor and which only look that way because of how they were built. A surprising amount of "dynamic" content on a typical site is actually identical for every visitor and could be cached safely; the personal part is often a small piece — a "logged in as" message in a corner, a cart count in the header — surrounded by content that never changes visitor to visitor.
Where only a small fragment of a page is genuinely personal, it is often possible to cache the page as a whole and load that one fragment separately — with a small script after the page loads, for instance — rather than deciding the entire page cannot be cached because of one line in the corner.
Exclude what genuinely cannot be shared
Some pages have to be excluded from page caching outright, because serving a cached copy to the wrong visitor is a real problem, not a cosmetic one:
- Cart and checkout pages, which show one visitor's order and payment details — see how to stop caching breaking your cart for the specifics.
- Account and dashboard pages, which show a signed-in visitor's own data.
- Any page containing a form with a security token tied to that specific visitor's session, since serving a cached copy would hand every visitor the same, invalid token.
Most caching plugins and configurations detect logged-in sessions automatically and skip caching for them by default — check this is actually working rather than assuming it, particularly after installing something new that touches sessions or authentication.
Set cache lifetimes that match how often content actually changes
A page that updates constantly does not need to be excluded from caching entirely — it needs a shorter cache lifetime that matches how quickly it goes stale. A page of live stock levels might reasonably be cached for a minute rather than a day; a static "about us" page can be cached far longer, because nothing about it changes between publishing decisions.
| Content type | Reasonable approach |
|---|---|
| Static or rarely edited pages | Long cache lifetime, cleared manually or automatically when the page is actually updated |
| Content updated on a schedule | Cache lifetime matching that schedule — a few minutes for near-live data, longer for daily content |
| Comments or user-submitted content | Short cache lifetime, or invalidate the specific page immediately when a new comment is approved |
| Anything logged-in or personal | Excluded from page caching entirely |
Invalidate on the event, not just on a timer
Relying purely on a cache expiring after a fixed time means visitors can see stale content for the entire duration between updates and the cache clearing. A better approach, where your platform supports it, is invalidating — clearing — the specific cached page the moment its content actually changes: the instant a post is published or edited, the instant a price is updated, the instant a comment is approved. This gets you the performance benefit of caching without the staleness cost of a long, fixed timer.
Object caching for the parts page caching cannot help
For pages that must be generated fresh for every visitor and cannot be cached as a whole page — a genuinely personalised dashboard, for instance — object caching still helps, because it caches the results of expensive individual operations, such as a specific database query, and reuses them across requests even when the page around them differs. This is a smaller win than caching the whole page, but it is not nothing, and it applies in exactly the cases where page caching is ruled out. Reducing database load on a busy site covers this alongside the other approaches to the same underlying problem.
A practical process
-
Map which pages are genuinely personal, per visitor
Cart, checkout, account and dashboard pages, plus anything with a session-specific security token.
-
Confirm those pages are actually excluded from caching
Check the configuration rather than assuming a plugin's defaults cover every case correctly.
-
Set cache lifetimes based on how often content changes
Not one blanket duration for the whole site.
-
Set up invalidation on publish or update where possible
So visitors see fresh content immediately rather than waiting out a timer.
-
Use object caching for anything that must stay fully dynamic
Reduces the cost of pages that cannot be cached as a whole, without needing to cache the page itself.
Getting this right takes more care than turning on a blanket cache and walking away, but it is what lets a site with real logins, carts and frequently updated content still get most of the benefit that a static site gets almost for free.
Related reading
Why rebuilding a page from scratch on every visit is expensive, and what caching actually does instead.
How to stop caching breaking your cartCache the wrong page and one customer starts seeing another customer's basket — here is exactly what to exclude and why.
How to reduce database load on a busy siteHow to find what is actually straining the database, and the maintenance most busy sites are quietly overdue for.
What is TTFB and why does mine look high?What the wait before the first byte actually measures, and the short list of things that usually cause it.