How to improve WordPress TTFB and LCP with better cache strategy

Slow Largest Contentful Paint (LCP) is not always a frontend problem. In one WordPress performance investigation, pages were visually rendering quickly once the response arrived, but Time to First Byte (TTFB) on lower-traffic pages was taking several seconds. The underlying issue was server-side caching behavior: personalized cookies were preventing visitors from sharing the same cached HTML, which forced expensive page generation far more often than expected.

The final solution combined cache-safe personalization, a cookie naming change, first-hit caching, hourly cache prewarming, and a longer cache lifetime. After deployment, location-style pages were consistently serving from cache in roughly 30 milliseconds during monitoring.

Issue background

The site used a shared WordPress template across many location-style pages. Frontend optimization had already reduced paint time to under roughly 300ms after the first byte arrived, yet real-user LCP remained elevated on several lower-traffic pages.

The performance pattern was especially revealing:

  • Some pages were seeing TTFB above 3,000ms.
  • Other pages using the same template could deliver TTFB near 1 second.
  • Lower-traffic pages were disproportionately slower.
  • Once HTML arrived, the browser could paint the page quickly.

That pointed away from images, CSS, and general frontend rendering as the primary bottleneck. The investigation instead focused on WordPress page caching, cookies, server-side personalization, scheduled jobs, and CDN behavior.

Diagnosis

Several possible causes were reviewed, including plugin overhead, Weglot, WP Rocket configuration, database queries, and page-cache behavior.

The first important finding was that some personalized elements were rendered on the server based on saved visitor preferences. That meant the server could produce slightly different HTML depending on the visitor’s cookies. Instead of one reusable cached copy of a page, the caching layer could end up treating variations as separate responses.

A deeper test uncovered an even more direct cache-bypass condition. A cookie used for saved visitor preferences began with the wp_ prefix. On the WP Cloud hosting stack, requests carrying that cookie were not being served through the normal edge cache. Returning visitors who had used the site’s save functionality could therefore receive a full uncached WordPress page build on every request.

On staging, the difference was dramatic: a request with the problematic saved-preference cookie could take around 3,400ms, while the same type of page returned from edge cache in roughly 2ms after the cookie issue was corrected.

The team also found a separate legacy diagnostic logger that wrote a database row on every physician-style page view. Its table had grown to roughly 8 million rows and about 11GB. Although this did not explain the entire regional TTFB pattern, disabling the logger removed an unnecessary database write from each affected page view.

Another key insight was that traffic volume was masking the problem. High-traffic pages were more likely to remain warm in cache, while quieter pages were more likely to expose visitors to uncached page generation. This is why pages using the same template could show very different real-world TTFB.

Resolution steps

The final performance strategy addressed both cacheability and cache warmth.

  1. Move visitor-specific rendering to the browser. Saved-location and saved-physician output was changed so the server sends generic cacheable HTML and JavaScript fills in each visitor’s saved preferences after the page loads. The user experience remains personalized without forcing WordPress to generate unique server HTML for anonymous visitors.
  2. Remove cache-breaking cookie behavior. The saved-preference cookies were renamed from a wp_ prefix to a cache-safe prefix, with a migration so existing visitors could move to the new cookie automatically. This allowed returning anonymous visitors to receive the same shared edge-cached page as other users.
  3. Keep anonymous HTML identical. Other cookie-dependent server rendering, including hero content variations, was shifted to client-side logic. The browser decides what to display while the cached HTML stays consistent.
  4. Enable first-hit caching. The PHP-level page cache previously required two visits within a 20-minute window before a page qualified for caching. The configuration was updated so pages can cache on the first visit. This particularly benefits low-traffic content that may never reach a multi-visit threshold quickly.
  5. Prewarm important pages. A scheduled cache-warming process was configured through WP Cloud to visit all key pages once per hour. This proactively keeps quieter pages warm so a real visitor does not have to absorb the first uncached request.
  6. Match cache lifetime to the warming schedule. The page cache window was extended from 30 minutes to 60 minutes. With hourly prewarming, this avoids a gap where a page could expire halfway through the hour and remain cold until the next warming run.
  7. Keep dynamic data independent from the page cache. Frequently changing data can be loaded through a separate API request after the cached page loads. This allows the HTML page itself to remain cached longer without forcing highly dynamic information to become stale.
  8. Remove unnecessary database work. The legacy diagnostic logger was disabled so page views no longer generated an extra database write into an oversized logging table.

During testing, PageSpeed Insights mobile results on a representative page improved from 3.3s LCP to 2.8s LCP. Another comparison showed LCP improving from 3.5s to 2.9s, while WebPageTest showed TTFB improvements on both cold and warm requests.

The most important gain, however, was not fully represented by standard lab testing. The cookie fix primarily helped returning visitors who previously bypassed cache entirely. After correction, those requests could be served from the edge cache instead of triggering multi-second WordPress page generation.

Final outcome

The final production configuration combined shared anonymous caching, browser-side personalization, cache-safe cookies, first-hit caching, hourly prewarming, and a 60-minute cache window.

After deployment, the hourly warming process ran repeatedly without misses during overnight monitoring, and key pages were consistently being served from cache in around 30ms. The setup also preserved the ability for frequently changing data to remain current independently of the longer page-cache lifetime.

The broader lesson is that WordPress TTFB and LCP problems can come from how a site varies HTML and cookies, not just from the number of plugins or the amount of frontend code. When identical templates have dramatically different performance, inspect whether cookies are bypassing the CDN, whether server-side personalization is fragmenting page cache, and whether low-traffic URLs are ever getting warm enough to benefit from caching.

If your WordPress site has slow TTFB, inconsistent LCP, or pages that perform differently despite sharing the same template, contact Freshy. Our WordPress team can investigate WP Rocket, CDN caching, cookies, server-side rendering, Core Web Vitals, and other performance bottlenecks.