---
title: Cache and hosting
---

The Convergence Cache module gives every site one cache-clearing interface regardless of host. This guide covers how a hosting provider is detected, how the module resolves which cache managers to use, and how to clear caches from PHP, REST, or the admin bar.

## Host detection

`Mantle\Helper\HostingProvider::detect_provider()` sniffs host-specific markers in a fixed order and returns the first match, or `unknown`.

<!-- wp:docspress/fields {"title":"Detection markers","description":"Checked in this order by <code>detect_provider()</code>. The first match wins.","fields":[{"name":"wpengine","type":"string","required":false,"defaultValue":"1","description":"WP Engine. Detected when the <code>is_wpe()</code> function exists and returns true.","values":"WP Engine","deprecated":false},{"name":"pressable","type":"string","required":false,"defaultValue":"2","description":"Pressable. Detected when the <code>IS_PRESSABLE</code> constant is defined and truthy.","values":"Pressable","deprecated":false},{"name":"cloudways","type":"string","required":false,"defaultValue":"3","description":"Cloudways. Detected when <code>IS_CLOUDWAYS</code> is defined and strictly equal to true.","values":"Cloudways","deprecated":false},{"name":"pantheon","type":"string","required":false,"defaultValue":"4","description":"Pantheon. Detected when the <code>PANTHEON_ENVIRONMENT</code> constant is defined, whatever its value.","values":"Pantheon","deprecated":false},{"name":"unknown","type":"string","required":false,"defaultValue":"fallback","description":"No marker matched. Host-specific purging is unavailable; generic layers still work.","values":"","deprecated":false}],"searchable":false,"compact":false} /-->

<!-- wp:docspress/callout {"tone":"note","title":"Cloudways detection is stricter than the others","content":"<p><code>is_cloudways()</code> requires <code>IS_CLOUDWAYS === true</code> exactly, whereas <code>is_pressable()</code> passes its constant through <code>mantle_string_to_bool()</code> and so accepts <code>'true'</code> or <code>'1'</code>. If Cloudways detection fails on a site where the constant is set to a string, that is why.</p>","collapsible":false} /-->

<!-- wp:docspress/diagram {"title":"Detection to purge","type":"flow","source":"detect_provider -> hosting_provider: write setting\nhosting_provider -> get_hosting_provider: read setting\nget_hosting_provider -> Cache managers: select host purge path\nSettings UI -> hosting_provider: manual override","caption":"The stored setting is authoritative at runtime, not live detection."} /-->

<!-- wp:docspress/callout {"tone":"warning","title":"The stored setting wins over live detection","content":"<p><code>Convergence_Cache_Module::get_hosting_provider()</code> reads the <code>hosting_provider</code> <em>setting</em>; it does not call <code>detect_provider()</code>. Detection populates that setting, but once stored it is authoritative. After migrating a site between hosts, update <code>hosting_provider</code> or the module keeps trying to purge the old host's cache.</p>","collapsible":false} /-->

## Verify what a site thinks it is

<!-- wp:docspress/terminal-session {"title":"Compare detected and stored provider","shell":"bash","prompt":"$","command":"wp eval 'echo \"detected: \" . \\Mantle\\Helper\\HostingProvider::detect_provider() . PHP_EOL;'\nwp eval '$s = new \\Mantle\\Model\\Settings(); echo \"stored:   \" . var_export( $s->get_setting( \"hosting_provider\" ), true ) . PHP_EOL;'","output":"detected: unknown\nstored:   ''"} /-->

That output is from a local development site, which matches no host marker. A mismatch between the two lines on a production site is the signal to correct the setting.

## Cache layers and routes

The module exposes a route per layer, plus host-specific purge routes. All require the `convergence_cache` module to be enabled.

| Layer | Route | Capability |
|-------|-------|------------|
| Object cache | `/mantle/v1/cache/clear/object` | `mantle_clear_cache_object` |
| Page cache | `/mantle/v1/cache/clear/page` | `mantle_clear_cache_page` |
| Edge or CDN | `/mantle/v1/cache/clear/edge` | `mantle_clear_cache_edge` |
| Everything | `/mantle/v1/cache/clear/all` | `mantle_clear_cache_all` |
| Pressable | `/mantle/v1/cache/clear/pressable` | — |
| WP Engine | `/mantle/v1/cache/clear/wpengine` | — |
| Pantheon | `/mantle/v1/cache/clear/pantheon` | — |
| Cloudflare | `/mantle/v1/cache/clear/cloudflare` | — |

<!-- wp:docspress/api-request {"method":"POST","endpoint":"/wp-json/mantle/v1/cache/clear/page","headers":"Accept: application/json\nContent-Type: application/json\nX-WP-Nonce: REPLACE_WITH_REST_NONCE","requestBody":"{\n  \"url\": \"https://example.com/about/\"\n}","requestBodyFormat":"json","responseStatus":"200 OK","responseBody":"{\n  \"success\": true\n}","responseBodyFormat":"json","runnable":false,"editable":true,"allowUnsafe":false,"timeout":10000} /-->

<!-- wp:docspress/callout {"tone":"warning","title":"Cache clearing is granted broadly by default","content":"<p>The four <code>mantle_clear_cache_*</code> capabilities are granted to <code>power_admin</code>, <code>administrator</code>, <code>editor</code>, <em>and</em> <code>shop_manager</code> out of the box — a deliberately wide grant so content editors can flush a stale page. On a high-traffic site, <code>mantle_clear_cache_all</code> in the hands of an editor is an origin-load risk. Narrow it with the <code>mantle_all_capabilities</code> filter if that matters.</p>","collapsible":false} /-->

## Providers and cache managers

The module separates two concepts, which is worth knowing when reading the source:

<!-- wp:docspress/fields {"title":"Providers versus cache managers","description":"Both live under <code>includes/Modules/Convergence_Cache/</code>.","fields":[{"name":"Providers","type":"string","required":false,"defaultValue":"Providers/","description":"Describe a platform and what it supports. Implementations: Cloudflare, Cloudways, Pantheon, Pressable, WPEngine, WPRocket. Each implements <code>Cache_Provider_Interface</code>.","values":"","deprecated":false},{"name":"Cache managers","type":"string","required":false,"defaultValue":"Cache_Managers/","description":"Perform the actual purge. Implementations: Cloudflare_API, Pantheon_Native, Pressable_API, Pressable_Plugin, WPEngine_Native. Each implements <code>Cache_Manager_Interface</code>.","values":"","deprecated":false}],"searchable":false,"compact":false} /-->

Note that Pressable has two managers — `Pressable_API` and `Pressable_Plugin` — because the purge can go through the hosting API or through Pressable's own plugin depending on what is available.

<!-- wp:docspress/file-tree {"root":"includes/Modules/Convergence_Cache/","tree":"Convergence_Cache_Module.php\nProviders/\n  Cache_Provider_Interface.php\n  Cache_Provider_Abstract.php\n  Cloudflare.php\n  Cloudways.php\n  Pantheon.php\n  Pressable.php\n  WPEngine.php\n  WPRocket.php\nCache_Managers/\n  Cache_Manager_Interface.php\n  Cache_Manager_Abstract.php\n  Cloudflare_API.php\n  Pantheon_Native.php\n  Pressable_API.php\n  Pressable_Plugin.php\n  WPEngine_Native.php\nAPI/REST/\n  Cache_Purge_REST_Controller.php\n  Module_Settings_REST_Controller.php\nHelpers/\n  Cache.php","caption":"Providers describe platforms; cache managers execute purges.","collapsible":true,"open":true} /-->

## Cloudflare configuration

Cloudflare is the one provider needing credentials in Mantle's own settings.

<!-- wp:docspress/fields {"title":"Cloudflare settings keys","description":"Part of the <code>mantle</code> settings option.","fields":[{"name":"cloudflare_cache_enabled","type":"boolean","required":false,"defaultValue":"false","description":"Enables the Cloudflare integration.","values":"true, false","deprecated":false},{"name":"cloudflare_api_key","type":"string","required":false,"defaultValue":"","description":"Cloudflare API key. A credential stored in a WordPress option.","values":"","deprecated":false},{"name":"cloudflare_email_address","type":"string","required":false,"defaultValue":"","description":"Cloudflare account email, paired with the API key.","values":"","deprecated":false},{"name":"cloudflare_zone_id","type":"string","required":false,"defaultValue":"","description":"Zone to purge.","values":"","deprecated":false},{"name":"cloudflare_use_alt_account","type":"boolean","required":false,"defaultValue":"false","description":"Use the alternate Cloudflare account credentials.","values":"true, false","deprecated":false}],"searchable":false,"compact":false} /-->

<!-- wp:docspress/callout {"tone":"danger","title":"cloudflare_api_key is stored in the options table","content":"<p>A global Cloudflare API key grants full account access, not just cache purging. Prefer a scoped API token where the integration accepts one, and never export the raw <code>mantle</code> option into a support bundle or repository. See <a href=\"../reference/settings.md\">Settings</a> for the other credential-bearing keys.</p>","collapsible":false} /-->

## Admin bar controls

`cache_admin_bar_enabled` adds cache controls to the admin bar for users holding the relevant capability, so editors can purge a page while viewing it. Toggle it at `/mantle/v1/cache/admin-bar/enable`.

## Troubleshooting

<!-- wp:docspress/troubleshooter {"title":"Cache clearing is not working","intro":"Three questions narrow almost every cache-clearing problem.","startId":"module","questions":[{"id":"module","question":"Is the convergence_cache module enabled?","yesLabel":"Yes, it is active","yesNext":"provider","noLabel":"No, or unsure","noNext":"enable"},{"id":"provider","question":"Does the stored hosting_provider match the actual host?","yesLabel":"Yes, they match","yesNext":"capability","noLabel":"No, or it is empty","noNext":"fix-provider"},{"id":"capability","question":"Does the user hold the capability for that cache layer?","yesLabel":"Yes","yesNext":"credentials","noLabel":"No, or unsure","noNext":"sync-caps"}],"outcomes":[{"id":"enable","status":"warning","title":"Enable the module first","content":"<p>With <code>convergence_cache</code> disabled, none of the <code>/cache/*</code> routes exist and requests return <code>404 rest_no_route</code>. Enable it, then retry.</p>"},{"id":"fix-provider","status":"error","title":"Correct the hosting_provider setting","content":"<p><code>get_hosting_provider()</code> reads the stored setting rather than detecting live, so a stale value sends purges to the wrong host. Compare <code>detect_provider()</code> against the stored value and update the setting.</p>"},{"id":"sync-caps","status":"warning","title":"Sync capabilities","content":"<p>POST to <code>/mantle/v1/capabilities/sync</code> so the <code>mantle_clear_cache_*</code> capabilities are written onto roles, then confirm the user's role holds the one for that layer.</p>"},{"id":"credentials","status":"neutral","title":"Check provider credentials","content":"<p>Module, host, and capability all look right, so the failure is most likely credentials or connectivity. For Cloudflare verify <code>cloudflare_api_key</code>, <code>cloudflare_email_address</code>, and <code>cloudflare_zone_id</code>. For Pressable and WP Engine confirm the host API or supporting plugin is reachable.</p>"}],"showProgress":true} /-->

## See also

- [Settings reference](../reference/settings.md) — every cache key.
- [REST API](../reference/rest-api.md) — the full route list.
- [Troubleshooting](../troubleshooting.md).
