Forma

HTML cache: static speed without giving up your CMS

How Forma writes real HTML for public URLs, keeps admin editing dynamic, and serves a fast site without waking PHP for every page view.

A CMS usually answers every request by starting PHP, reading the database, rendering a template, and sending HTML. That is flexible. It is also unnecessary work when the page has not changed since the last visitor.

Forma’s HTML cache takes a simpler approach: when content changes, Forma renders the public URL once and writes the result as a real .html file. Apache can serve that file directly on every ordinary visit. PHP does not have to wake up just to say the same thing again.

That gives Forma the delivery model of a static site generator without replacing the editing workflow that makes a CMS useful.

PHP cache and HTML cache are different

Under Settings → Cache, Forma has two independent controls:

  • PHP cache stores rendered responses in SQLite. It skips repeated Markdown and Twig work, but PHP still handles the request.
  • HTML cache writes complete pages under fallback/. Apache serves those files before the PHP front controller.

Use either one, both, or neither. Turning HTML cache off returns Forma to its normal dynamic PHP behavior. The database remains the source of truth in every mode.

What gets written

Forma publishes files for stable public URLs:

  • pages, including the homepage;
  • published blog posts and the blog archive;
  • public podcast episodes and the podcast archive;
  • branded 403, 404, and 500 pages.

A save updates the affected file automatically. Change a post and Forma rebuilds that post plus the blog archive. Change a shared snippet or a sitewide setting and Forma republishes the site because the change may appear everywhere.

You can also use Rebuild HTML cache to regenerate everything in one pass. This is useful after a theme-wide edit, migration, or deployment.

What stays dynamic

Some URLs are questions, not documents. Forma deliberately leaves these in PHP:

  • /admin and every admin action;
  • /api and the scoped Agent API;
  • /search?q=...;
  • feeds, robots.txt, and sitemap.xml;
  • previews and other request-specific behavior.

The distinction is clean: files for real URLs; PHP for ad-hoc questions.

A search result depends on the query. An API response depends on the token and request. Those should not be frozen into a public file. A product page that changes only when an editor saves it should be.

Why this is more resilient

Static delivery reduces PHP work during normal traffic, but the bigger benefit is graceful failure. If PHP-FPM or FastCGI has a bad afternoon, Apache can still serve the published pages already on disk.

Forma also exposes /up as a PHP heartbeat. Monitoring can distinguish “the site is reachable” from “PHP is healthy.” A static fallback/php-ok.json stamp records the last time PHP completed a request, which makes hosting problems easier to diagnose.

HTML cache is not a substitute for backups or monitoring. It is a practical extra layer: public content keeps working while you investigate the dynamic layer.

Turn it on safely

  1. Open Settings → Cache.
  2. Enable HTML cache.
  3. Click Rebuild HTML cache.
  4. Visit the homepage, a page, a blog post, /search, and /up.
  5. Confirm that edits appear after saving.

That is the entire workflow. You do not deploy a separate generated site, maintain a second content tree, or teach editors a new command. SQLite holds the content; the HTML directory is derived output that Forma can rebuild at any time.

For brochure sites, documentation, portfolios, and content-heavy client sites, this is usually the best of both worlds: a tiny CMS when you edit and plain files when people read.