Stale cache content served after post update – Ghost file‑system cache
0 reputation · 02 Jun 2021, 07:37 UTC
0 reputation · 02 Jun 2021, 07:37 UTC
Goal: achieve immediate, selective removal of the cached HTML for a specific post when its content is updated via the Ghost admin API, avoiding a full cache flush.
Constraint: Ghost’s file‑system cache under content/data/cache/ is only invalidated by time‑to‑live expiration or by the ghost cache clear command, which deletes the entire cache directory and can cause load spikes on high‑traffic sites.
Uncertainty: the documentation notes the lack of a built‑in selective cache‑invalidation webhook or configuration option, leaving administrators to rely on TTL or manual full purges.
Questions: Is there a supported method to trigger deletion of the individual cache file for a updated post through the admin API or a webhook? Can the cache TTL be set per‑route or per‑post to achieve faster invalidation without a full flush? Are there any upcoming features or community plugins that provide selective cache purging for Ghost?
Ghost does not expose an API endpoint or webhook that tells the file-system cache to delete the cached HTML for a specific post. Invalidation occurs only by the global TTL expiration or by running ghost cache clear, which removes the entire content/data/cache/ directory.
content/data/cache/ with names that are the MD5 hash of the full request URL (including query string).cache.maxAge in config) and the ghost cache clear command.post.update webhook is fired when content changes, but its payload contains no instruction for the cache layer.ghost-cache-purge implement selective purging by listening to that webhook, computing the MD5 hash of the post's public URL, and deleting the matching cache file.post.update event from Ghost.url field from the payload or build it from your site's base URL and the post's slug).content/data/cache/<hash> if it exists.const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
function purgePostCache(postUrl) {
const hash = crypto.createHash('md5').update(postUrl).digest('hex');
const cacheFile = path.join(process.env.GHOST_CONTENT || '.', 'data', 'cache', hash);
if (fs.existsSync(cacheFile)) {
fs.unlinkSync(cacheFile);
console.log(`Purged cache file for ${postUrl}`);
} else {
console.log(`No cache file found for ${postUrl}`);
}
}
// Example webhook handler (Express)
app.post('/ghost/webhook', (req, res) => {
const event = req.body;
if (event.event === 'post.update' && event.post) {
const baseUrl = 'https://example.com'; // replace with your site URL
const postUrl = `${baseUrl}/${event.post.slug}/`;
purgePostCache(postUrl);
}
res.sendStatus(200);
});
If you prefer not to run a custom service, you can reduce the global TTL in config.production.json:
{
"cache": {
"maxAge": 10
}
}
After changing the value, restart Ghost (ghost restart). This makes stale content disappear faster, but the setting applies to every route and will increase origin traffic.
Please confirm your Ghost version (run ghost version) to ensure the behavior described still applies; if you are on a newer release, check the changelog for any changes to caching or webhook payloads.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.