
Most WordPress caching plugins promise faster page loads by storing static HTML and serving it to every visitor. That works beautifully—until someone logs in. Then the plugin faces a choice: serve the cached page and risk showing the wrong content, or bypass the cache entirely and slow the site back down.
The default behavior varies wildly across plugins, and most solo operators don’t notice the problem until a reader reports seeing someone else’s dashboard, a broken checkout flow, or stale course-access gates.
What full-page caching actually does
Full-page caching generates a static HTML snapshot of each URL the first time someone visits it. Subsequent visitors get that snapshot instead of triggering PHP, database queries, and theme rendering. The speedup is dramatic—page load times drop from 800ms to under 100ms.
But that snapshot is user-agnostic. It doesn’t know who’s viewing it. If the first visitor was logged out, the cached page shows a logged-out state. If you’re running a membership site, a course platform, or even just WordPress comments with reply threading, that’s a problem.
Most caching plugins handle this by disabling the cache entirely for logged-in users. WP Rocket, W3 Total Cache, and WP Super Cache all do this by default. The moment you log in, you’re back to slow, uncached page loads.
That’s fine if you’re the only one logged in. It’s not fine if you’re running a membership site with 500 active students, or a community forum where everyone has an account.
The exceptions list: what to exclude
Every caching plugin includes an exclude list—URLs or cookies that bypass the cache. The problem is that the defaults are conservative, and the documentation rarely explains why each rule exists.
Here’s what typically needs exclusion:
- Cart and checkout pages. WooCommerce, Easy Digital Downloads, and MemberPress all set cookies that modify page content. Cache those, and users see each other’s cart totals.
- Account dashboards. Any page showing user-specific data—order history, profile settings, course progress—needs to bypass the cache.
- Dynamic forms. Contact forms, quiz plugins, and conditional-logic forms often rely on nonces or session tokens. Cached nonces expire, and form submissions fail.
- Personalized content blocks. If you’re using a plugin that shows different CTAs, testimonials, or upgrade prompts based on user role, those blocks need to load fresh.
The tricky part: most plugins let you exclude by URL slug (/account/, /checkout/) but not by user role. That means you can’t serve cached pages to free members while bypassing the cache for paid members viewing the same URL.
The two-tier workaround: fragment caching
If you need fast page loads for logged-in users and personalized content, you need fragment caching—where parts of the page are cached, but user-specific elements load dynamically.
This isn’t built into most full-page caching plugins. You need a CDN or a caching layer that supports Edge Side Includes (ESI) or a JavaScript-based approach where the page skeleton loads from cache and an AJAX call fetches user-specific content.
Cloudflare Workers, Fastly, and some managed WordPress hosts (Kinsta, WP Engine) support ESI. For solo operators on shared hosting, the easier path is often to skip full-page caching for logged-in users entirely and optimize the uncached experience instead—faster database queries, lazy-loaded images, deferred JavaScript.
Configuration that actually works
Here’s a baseline exclude list for a typical membership or course site running on WordPress:
- Any URL containing
/my-account/,/dashboard/, or/profile/ - Cart, checkout, and thank-you pages (plugin-specific slugs)
- Any page using the
wordpress_logged_in_*cookie - AJAX endpoints (
/wp-admin/admin-ajax.php) - REST API routes serving dynamic data (
/wp-json/if you’re using it for frontend updates)
Test this by logging in, visiting a cached page, and checking the HTTP headers. Look for X-Cache: HIT or X-Cache: BYPASS. If you see HIT on a page that should be personalized, add it to the exclude list.
Most caching plugins also let you exclude by query string. If you’re running A/B tests or tracking UTM parameters, make sure those aren’t triggering separate cache entries—you’ll bloat storage and fragment your cache hit rate.
One more thing: if you’re using a managed host with server-level caching, check whether their rules override your plugin settings. Kinsta and Flywheel both have their own caching layers that ignore plugin configurations. You’ll need to contact support or use their dashboard to adjust exclusions.
Want more deep dives on the infrastructure behind online businesses? Subscribe to One Two Three Send—one focused article like this, delivered weekly.
