Skip to content
WP Visibility

Indexing and technical SEO guide

SEO Changes Not Showing on WordPress: Trace the Cache Serving Them

Compare the saved value with what an anonymous visitor receives, read the cache headers to find the layer holding the old page, and purge only that layer.

Published

On this page

When a new title, description, canonical, or robots setting does not show on the live page, compare three things before editing again: the value saved in WordPress, the HTML an anonymous visitor receives, and the response headers that say which cache answered. If the saved value is right and the public HTML is old, a cache between the two is serving a stored copy. Find that layer and purge the affected URL there. Repeated edits in the editor change nothing a cache is not passing through.

This guide covers stale output on your own site. What Google shows in results is a separate question: it reflects Google’s last crawl and its own choices about titles and snippets, and it changes on Google’s schedule, not when you purge a cache. Google’s title link documentation says title links are generated automatically and that Google has to recrawl and reprocess a page to notice updates, and its snippet documentation says snippets are created automatically, primarily from page content (both checked September 27, 2026).

Compare the editor value and the public response

Start by confirming what WordPress has stored. For a post using WP Visibility, print its SEO fields (post ID illustrative):

wp visibility get 42 --format=json

The command, listed in the WP-CLI reference, prints the stored fields with defaults filled in. With another SEO plugin, use its own screen or wp post meta list 42 to read what it saved.

Then fetch the page as an anonymous visitor, with no cookies:

URL="https://garden.example/garden-design/"

curl -s "$URL" | grep -ioE '<title>[^<]*</title>|<meta[^>]*name=.(description|robots).[^>]*>|<link[^>]*rel=.canonical.[^>]*>'

The address is illustrative. The pattern accepts either quote character because WordPress core’s wp_robots() prints the robots tag with single quotes (checked September 27, 2026). Three outcomes:

  • The public HTML shows the new value. The site is up to date. If your browser still shows the old one, the browser cache is holding it; open a private window.
  • The public HTML shows the old value, but a signed-in view shows the new one. A page cache or CDN is serving anonymous visitors a stored copy. Page caches are commonly set to skip signed-in users, as the cache rules on WordPress’s Nginx handbook page do (checked September 27, 2026), which is why the editor looks right.
  • Both show the old value. The change may not have saved, may be overridden by a template or another plugin, or may come from a different source. The duplicate tag guide covers finding which component prints the tag.
Find the layer holding the page. Saved value: What WordPress stored for the page. Anonymous response: What a signed-out visitor receives. Cache headers: Which layer answered and how long ago.
Three comparisons that locate stale SEO output before any purge. They cover your own site; search results update separately after a recrawl.

Identify the stale cache layer

A WordPress page can pass through several caches on its way to a visitor. Each one keeps its own copy and its own expiry.

Layer What it stores Typical signs in headers
Browser The page for one visitor Nothing on the server side; a private window shows the difference
CDN or proxy Whole responses at edge locations Age, cf-cache-status, x-cache, via
Page cache (plugin or host) Whole HTML pages at the origin Plugin or host headers, or an HTML comment at the end of the page
Persistent object cache Database query results and options No header; lasts beyond one request only with a persistent caching plugin

Read the headers of the anonymous response:

curl -sI "$URL" | grep -iE '^age:|cache|^via:|^x-|^date:|^last-modified'

The Age header, per MDN, checked September 27, 2026, is the time in seconds an object has been in a proxy cache. A large value means an intermediate cache answered with a copy it has held that long; MDN notes that 0 probably means the object came from the origin server. Cloudflare’s cache status documentation, checked September 27, 2026, defines HIT as found in Cloudflare’s cache and MISS or EXPIRED as served from the origin. Other CDNs use their own header names; check your provider’s documentation.

Also look at the last lines of the HTML. Some page cache plugins add a comment with the time the page was cached; the WP Super Cache plugin page, checked September 27, 2026, documents a “Cached page generated by WP-Super-Cache on” comment with a date and time:

curl -s "$URL" | tail -n 5

To separate the CDN from the origin, request a variant the cache is unlikely to hold, then compare:

curl -s "$URL?cachetest=$(date +%s)" | grep -io '<title>[^<]*</title>'

If the unique address shows the new title and the plain one shows the old, a cache keyed on the full URL is holding the plain address. If both are old, the origin itself is probably producing old output, which points to a page cache at the origin or to the saved value itself. Some caches ignore query strings, such as Cloudflare’s Ignore Query String caching level (checked September 27, 2026), so a same-as-before result is not proof on its own. If your host lets you request the origin directly, for example with curl --resolve to the origin IP, that removes the CDN from the test.

A persistent object cache is a less likely cause after a normal save, because WordPress’s clean_post_cache(), called by wp_insert_post() among others, deletes the post from the cache (checked September 27, 2026). It can matter when values were changed directly in the database, bypassing WordPress functions. WordPress’s object cache reference, checked September 27, 2026, says the object cache is not persistent by default and lasts only for one request unless a persistent caching plugin is installed. Check with wp cache type (checked September 27, 2026):

wp cache type

Default means WordPress’s own per-request cache. A result naming Redis, Memcached, or another backend means a persistent cache is present.

Purge narrowly

Purge the layer you identified, for the URLs affected, rather than clearing everything everywhere.

  1. Page cache plugin or host cache. Use its purge-this-page action, or its CLI or dashboard. If your plugin is meant to purge a post’s page when you update it and that did not happen, check its rules for which pages it clears on save.
  2. CDN. Purge by URL in the CDN’s dashboard or API. Include both the trailing slash and non-trailing slash versions if both are cached.
  3. Object cache. After a direct database change, wp cache flush clears it. Its WP-CLI documentation, checked September 27, 2026, warns of the performance impact in production and notes that on multisite it typically flushes the cache for all sites.
  4. Browser. A private window or a hard reload.

Purge wider when the change was wider. A new title template, separator, or robots setting in the site settings can change the head of many pages at once, so a full page cache and CDN purge is appropriate there. A single post’s description needs only that post’s URL. Sitemaps have their own cache: WP Visibility caches each sitemap document for up to a week and rebuilds it on the next request after a post is saved or deleted or a term is edited or deleted. After changes made another way, such as a settings change, wp visibility flush marks them stale. A CDN may still hold the sitemap URL, so purge it there too if needed.

Check the Cache-Control header while you are there. The MDN Cache-Control reference, checked September 27, 2026, explains that s-maxage sets freshness for shared caches such as CDNs and max-age for all caches. A very long s-maxage on HTML pages can explain why changes take days to appear, and whoever manages the CDN can shorten it for HTML.

Confirm representative pages

After purging, rerun the anonymous fetch and header check on:

  • the page you changed;
  • another page of the same type, to catch template-level changes;
  • the home page, if the change was site-wide;
  • the sitemap, if the change affects inclusion.

The headers should now show a fresh response, such as a small Age or a MISS followed by a HIT on the next request, and the HTML should carry the new value.

When the site is correct but search results are not, the remaining delay is Google’s. Its URL Inspection help, checked September 27, 2026, explains that the tool shows the most recently indexed version by default and offers Test live URL for the page as it is now. A live test that shows the new value confirms your site is serving it. The indexed version updates after Google recrawls, and a request for indexing does not guarantee when or whether that happens.

Keep a note for next time

Write down, for the site, which caches exist and how to purge each: the page cache plugin or host setting, the CDN account and purge method, whether a persistent object cache is installed, and the Cache-Control values for HTML. The next person who finds an old title on the live site can then go straight to the right layer.

Read next

WordPress SEO with your own assistant.

WP Visibility is $99 a year for unlimited sites, client sites included, with a 30-day refund. Use its SEO tools in WordPress or connect a supported assistant. Read how proposal review and permissions work.