Challenges with Blitz Cache in complex Craft CMS multisites

Server load and resource usage

In large multisite projects, Blitz can put a serious load on the server. Generating and updating thousands of static pages consumes a lot of CPU and RAM. Especially cache warming (pre-rendering all pages) and invalidation after changes can become bottlenecks. In one setup with around 10,000 cacheable pages, the cache reached 2.4 GB. Clearing or rebuilding it regularly caused timeouts — even via the URL API or the backend utility.

Background processes like cache-clear jobs can run for hours or pile up depending on the size of the project. In one case, a small change in a large system kept a job busy for over two hours. According to the documentation, this often results from PHP limits (timeouts, insufficient RAM). The recommendation: run the Craft queue as a daemon and increase PHP limits. Without such optimization, Blitz may deliver pages faster but can push the server to its limits when refreshing the cache.

Things get especially tricky when the cache has to be rebuilt after content changes. If content is heavily interlinked or templates don’t use eager loading, the number of database queries skyrockets. Blitz 4.4 reduces the required queries, but the process remains heavy. One extreme example: 130 sites in one installation. A single global content change triggered dozens of timeouts because the cache for all sites was rebuilt at once. This shows that Blitz can hit technical limits in very large setups.


Cache invalidation with frequent updates

Another major issue is cache invalidation. When editors change content, Blitz automatically updates the affected pages. With frequent edits, this can lead to constant re-caching — caches are continuously cleared and rebuilt. This can cause delays, for example when new content doesn’t appear immediately on the frontend.

Scheduled publishing is a common example: a post was published on time but didn’t appear because the cache hadn’t refreshed yet — the old version stayed live. Cron jobs can help, but that adds setup complexity.

With many editors working across multiple sites, someone is always making changes — meaning Blitz is constantly rebuilding caches somewhere. This keeps the queue and database under permanent load. Some developers recommend softening automatic invalidation, e.g. refreshing every X minutes instead. It reduces load but makes updates less immediate.


Dynamic content and template compatibility

Blitz is a static cache — meaning personalized content doesn’t fit naturally. Content that changes per user (e.g. greetings, carts) can’t be directly cached. Blitz would otherwise serve the same HTML to everyone — including other users’ sessions. These dynamic sections must be excluded and loaded via JavaScript or AJAX.

Blitz offers placeholders and Sprig support, but it’s not trivial. For example, a shop may load price data via AJAX only for logged-in users. If misconfigured, the page might show the guest version instead — or fail to update the CSRF token correctly. With modern JS frameworks (e.g. PJAX navigation), you must also ensure Blitz’s inject script fires properly — otherwise forms may keep outdated tokens.

Complex template structures can also cause issues. When many relational queries are involved, Blitz can struggle to track dependencies efficiently — one case saw the tracking table grow to over 886,000 entries. Disabling tracking can help but means developers must manage dependencies manually.


Multisite challenges

In multisite environments, problems multiply. Each site has its own URLs, content, and cache. Blitz must manage them separately. Configuration becomes more complex — URI patterns, base URLs, and deployment targets must all be defined per site. Misconfigurations can easily lead to only the main site being cached correctly.

A known issue was incomplete invalidation after entry changes: for example, disabling the German version of an entry sometimes left the static page active — it appeared online even though it was unpublished. Manual clearing was required. This has since been fixed (as of Blitz 4.13.0), but it highlights the complexity of such setups.

Global content also affects all sites — if an editor changes a global field, Blitz clears all caches. This can surprise teams working on just one language version. Fine-grained site-level control is limited. With 130 sites, one small change can trigger 130 clear operations. Deployment also requires care — each site needs separate paths, domains, or CDN targets.


Maintenance and scalability

Blitz is not a “set it and forget it” plugin. The larger the setup, the more maintenance it needs. Best practices include:

  • Run cache clears via CLI instead of the backend (to avoid timeouts)
  • Use cron jobs for scheduled refreshes
  • Disable file counting in the control panel for large caches
  • Define dependencies manually using source tags
  • Keep plugin updates in check (e.g. for header or multisite fixes)

Blitz scales — but not for free. Large setups need more hardware and thoughtful configuration. In some cases, server-side caching alternatives like Nginx FastCGI or external CDNs are simpler. Blitz supports such integrations (e.g. via Cloudflare purge integration), but those also require upkeep.


When Blitz makes less sense

In the community, Blitz is seen as powerful — but not always ideal. It’s generally discouraged:

  • For heavily personalized content (e.g. member areas, custom pricing)
  • When content updates occur minute by minute
  • When other caching systems or CDNs are already in use
  • For extreme setups with thousands of sites, where maintenance and performance spiral out of control
  • In e-commerce projects with dynamic elements (e.g. carts, checkout)

In such cases, fragment caching, Sprig components, query optimization, or a caching strategy without full-page static caching often work better.