Note #2026-07-04-001

Srijan Choudhary Srijan Choudhary

In reply to mauricerenck/komments

SQLite comment storage (v3) breaks page-cache invalidation (staticache): comments show in Panel but not on cached pages

Summary

Since v3 moved comment storage from inline content-file fields to SQLite, komments no longer triggers Kirby's page-cache invalidation when a comment or webmention changes. On any site that uses a page cache — in particular the official getkirby/staticache — new comments show up in the Panel (which reads the DB live) but never appear on the public page, which keeps serving stale cached HTML until the page's content file happens to be edited for some unrelated reason.

This is effectively a silent regression for anyone who paired komments with a page cache.

Root cause

  • In v2, received comments/webmentions were written into the page's content file. A content-file write is a page change, so Kirby automatically flushed that page's cache and the public page updated on the next request — invalidation came "for free" as a side effect.
  • In v3 with storage.type => 'sqlite', comments are written to the SQLite DB and the content file is never touched. Kirby only invalidates a page's cache entry when the page/model itself changes, so nothing flushes the cache. $page->comments() reads live from the DB on render, but with a page cache active the cached HTML is served without render() ever being called.

Steps to reproduce

  1. Kirby with page caching enabled, e.g. getkirby/staticache (cache.pages.type => 'static').
  2. komments v3 with storage.type => 'sqlite'. Webmentions auto-publish by default; comments via a moderated-then-published flow.
  3. Visit a post once to prime the cache.
  4. Receive a webmention (or publish a comment) for that post.
  5. Panel shows the comment; the public page does not (stale cached HTML). It only corrects itself if the page's content file is later edited.

Expected

Adding, publishing, or removing a comment/webmention for a page should mark that page's cache stale, so the next request re-renders with the current comments.

What already works vs. the gaps

komments already fires hooks integrators can subscribe to for cache invalidation:

  • komments.comment.received
  • komments.comment.replied
  • komments.comment.published (fires on the publish/unpublish toggle, both directions)

But several mutations that change public output fire no event at all, so there is no way to invalidate on them:

  • deleteComment / deleteCommentsInBatch (moderation delete) — no trigger
  • flagComment / flagCommentsInBatch (spam/flag, which can hide a comment) — no trigger

These live under the plugin's api routes, so they also can't be caught via Kirby's route:after hook (that only fires for the front-end router, not the Panel API), and there is no API-level hook. So today a delete or spam-flag can't be reliably detected by an integrator.

Suggestions (any one would help)

  1. Emit a complete set of mutation hooks. Add triggers for delete and flag and their batch variants — e.g. komments.comment.deleted / komments.comment.flagged — mirroring the existing received / published / replied events. A complete event surface lets integrators reliably purge the cache for the affected page(s).
  2. Optional built-in page-cache purge. When a comment for a page changes, remove that page's entry from kirby()->cache('pages') (driver-agnostic — works for file, APCu, Redis, and staticache alike). Could be gated behind an option such as mauricerenck.komments.flushPageCache => true.
  3. At minimum, document the caveat. Note in the SQLite-storage docs that DB storage no longer auto-invalidates page caches, and that integrators using a page cache must wire up invalidation via the hooks above.
Tagged: issues

Responses · 3

  • Cthulhux

    I presume that using type==markdown is still not having this issue? CC'ing myself, because I think this is a serious problem in komments's design and I plan to use it soon...

    Reply
  • Maurice Renck

    I added new hooks, for now with basic data in them, but as you can only flush the whole cache not a single page, this is a good first step I guess. There are now new hooks for deleted and flagged, following the exiting naming schema, but there is also another hook: komments.comment.changed which fires whenever something is changed in the moderation view, so this would probably be a good one for flushing caches alongside the published or received hooks. The full list is now here: https://maurice-renck.de/kirby/komments/reference/hooks I will look deeper into all this with the new major version already in the planning. The goal will be to simplify things and make integrating the plugin easier. This will also separate Webmention rendering from comments. I will write about this in some detail soon. But all those changes will take some time. @dertuxmalwieder I don't see a serious design problem here. This is basically how Kirby + caching works; using the hooks should enable you to flush caches when needed. I also think the plugin should not flush those caches on its own; I feel this is a behavior reaching too deep into the authority of the site owners. I don't recommend using markdown storage, as I plan to remove it in the future; there were too many timing issues with sites receiving a lot of comments.

    Reply
  • Cthulhux

    I don't recommend using markdown storage, as I plan to remove it in the future; there were too many timing issues with sites receiving a lot of comments. Makes sense. My bad.

    Reply