Skip to content

Caching and Purging

webdesign29 edited this page Jun 13, 2026 · 1 revision

Caching & Purging

The Cache module is the headline feature. It lets bext keep a long TTL while WordPress keeps the cache fresh by purging exactly the URLs that change.

How a purge reaches bext

All purges go to the bext main listener:

POST  http://127.0.0.1/__bext/cache/purge-proxy     (Auto mode)
POST  https://<cloud-endpoint>/__bext/cache/purge-proxy   (Cloud mode, + bearer token)

{ "host": "example.com", "paths": ["/about/"], "prefixes": [] }
→  {"purged": 1, "host": "example.com", "paths_count": 1, "prefixes_count": 0}

This endpoint runs invalidate_paths() / invalidate_prefix() on the in-memory FastCGI cache that serves WordPress pages, honoring paths and prefixes. It is surgical: one URL → one eviction.

⚠️ Earlier builds posted to the cache-purge port's /nginx-cache/purge-site, which drops paths and only wipes disk files — a no-op for WordPress. v0.2.0+ uses purge-proxy.

Purge on save (automatic)

When Purge on save is enabled (default), these events queue a purge:

Event Hooks
Post published / updated / unpublished / deleted transition_post_status, save_post, before_delete_post
Terms (categories, tags, custom taxonomies) created_term, edited_term, delete_term
Menus, Customizer, theme switch, key options wp_update_nav_menu, customize_save_after, switch_theme, updated_option
Comments wp_insert_comment, transition_comment_status
WooCommerce products / stock woocommerce_update_product, woocommerce_new_product, woocommerce_product_set_stock, woocommerce_variation_set_stock

What gets purged for a post

The permalink plus everything that lists it:

  • the post's permalink
  • the home page
  • the post-type archive
  • the author archive
  • every term archive the post belongs to (category/tag/custom-tax)
  • the main feed + comments feed
  • the sitemap (core wp-sitemap.xml, Yoast/RankMath sitemap_index.xml, sitemap.xml)
  • the REST collection (/wp-json/wp/v2/posts)

All paths are derived from WordPress (get_permalink, get_term_link, get_feed_link, get_sitemap_url, rest_url) and the install base path, so subdirectory installs (site at /blog/) purge the right URLs. Customize the set with the bext/purge_urls_for_post filter.

Coalesced + non-blocking

URLs queued during a request are de-duped and flushed once on shutdown, after fastcgi_finish_request() — so the editor's response returns immediately and never waits on the purge.

Site-wide changes

Menu/theme/permalink/option changes purge the whole site (prefix /). On subdirectory multisite, this is scoped to the blog's path so it doesn't wipe sibling blogs.

Personalization-safe headers

On the front end the module sends Cache-Control: private, no-store, max-age=0 for logged-in, WooCommerce-cart, comment-author, and preview requests — so bext never caches a personalized page under the anonymous key. (bext also bypasses on auth cookies; this is belt-and-braces.)

Anonymous pages optionally get a positive Cache-Control (the Anonymous Cache-Control setting or the bext/anonymous_cache_control filter); leave it blank to defer to the bext vhost config.

Manual purge

  • Admin bar → Purge bext cache (whole site) and Purge this URL (the current page).
  • WP-CLI: see WP-CLI.
  • The Dashboard shows a Purge entire cache button and a log of recent purges.

Clone this wiki locally