Guide 12 · Developer docs

Performance, caching, deployment and go-live

How Core dna caches pages, what makes a render fast, how code reaches a site and what stays behind, the go-live checklist, and running a site once it is live. For developers, leads and site operators who already build pages in a theme repository.

L2–L3
Unit 01 · The caching model

Authenticated requests and the cache

The rule behind every member-area and cart performance question: a signed-in render is never stored, while a stored page is served without asking who you are. What follows for member areas, carts and public pages, and how to tell which case you are in.

Who this is for. Developers building member areas, carts or anything personal on a site that caches. Afterwards you can predict which requests are served from the cache, which render, and why a personal element on a public page needs a fragment.

The rule has two halves. A response rendered for a signed-in visitor is never written to the page cache. But the page cache is read before the platform knows who is asking, so a page that is stored is served to everyone, signed in or not. A third, smaller effect sits beside them: a request that carries a session cookie or an Authorization header does not use the shared Memcached layer while it renders.

The rule

Signed-out visitorSigned-in member
Served a stored page, if one exists for the URLYesYes
A rendered response written to the page cacheYes, if cacheableNo
Shared Memcached used while renderingYes, on production, unless the request carries PHPSESSIDNo: a signed-in member always carries PHPSESSID

The middle row is the half people know. The first row is the one that surprises them: the page cache is answered from a file before the application starts, its key is the hostname, the path and the declared query parameters, and no cookie or header is part of it. Tested on a production Core dna site in October 2026: requests carrying a token cookie, a PHPSESSID cookie or an Authorization: Bearer header all came back X-Cache-Status: hit with X-Authenticated: 0, the copy rendered for an anonymous visitor.

The members guide states the same rule from the member's side, with the fragments that follow from it: A member site and the page cache.

What it means for member areas and carts

A member area and a cart are fast because they are small, not because they are cached: every request for them renders. Pages under /my-account send a signed-out visitor to the sign-in page, so no anonymous 200 is stored for them, and a signed-in render is never stored either. The cart and checkout routes prevent caching themselves. Their cost is the render, so the template habits in Making pages fast (query-per-row, nesting) matter more on those pages than anywhere else.

A public page is the opposite case. The first anonymous visitor's render is stored and every later visitor gets it, members included. Anything personal on it, such as a name, a cart count or a members-only banner, is either missing for members or, worse, shows someone else's. That is why the personal parts of a public page are fragments, fetched by the browser from a URL that renders for each visitor (Hybrid builds, a cached shell with member fragments).

What it protects, and what it does not

  • It protects members from each other. Nothing rendered for a member is written to a shared copy, so one member's details cannot be stored and served to another.
  • It does not protect a public page from anonymous assumptions. A template that branches on $_currentUser->isLoggedIn() on a public page is right for the request that rendered it and wrong for everyone after.
  • It does not decide access. Access to a members-only record is checked when the record is loaded, so a restricted page is never rendered for an anonymous visitor and never stored. It is the public pages that link to it, or list it, that need care.
  • It does not cover the browser. A member's browser may keep its own copy of a public page for the rest of the page's lifetime (the CDN and the browser).

The Memcached half

The shared Memcached layer holds framework internals, not your content (shared Memcached). A request with a PHPSESSID cookie or an Authorization header skips it and works from the in-request cache alone, so the framework repeats set-up work, such as reading entity metadata, that an anonymous request finds ready. Two consequences:

  • Every render for a signed-in member does a little more work than the same render for a visitor. That is the price of the session, and another reason member pages should be small.
  • An integration calling the API renders without Memcached on every call. Fewer, larger requests cost less than many small ones (Shaping the response with properties).

Checking which case you are in

Two response headers answer it. X-Authenticated is 1 when the platform rendered the response for a signed-in user and 0 otherwise, including on every page served from the cache. X-Cache-Status says whether the response came from the page cache (reading the headers). Look at them as a member in the browser's Network panel, then for the same URL signed out:

Shell
curl -s -o /dev/null -D - https://www.example.com/events | grep -iE 'x-cache-status|x-authenticated|cache-control'

If a member sees X-Authenticated: 0 and X-Cache-Status: hit on a page that should know who they are, the page is stored and served to everyone. Move the personal part into a fragment, or, if the whole page is personal, prevent caching on it (preventCaching() and fragments).

Go deeper

Was this page helpful?

Your answer goes to the docs team.