Craft CMS best practices

Performance and stability best practices for Craft CMS on TurboStack - Varnish full-page cache, Redis, OPcache, cache warming, image transforms and production config.

Craft CMS renders pages from a database and a Twig template layer, so a fast site depends on effective caching and a primed page cache. TurboStack provisions the stack and warms the cache on a schedule. This page covers what is already configured and how to use it effectively.

What TurboStack configures for you

When you deploy a craftcms app, the platform sets up a Craft-aware stack:

  • Document root - the vhost serves from your app's public_html directory (/var/www/<user>/[<app>/]public_html), with a Craft-specific Nginx configuration (50main.conf). Static assets (js, css, images, webp) are served with long expires headers, and PHP requests are routed to a per-site PHP-FPM backend with an extended fastcgi_read_timeout for long-running admin operations.
  • Varnish full-page cache - when Varnish is enabled, the platform installs a Craft-aware VCL. It bypasses the cache for the control panel (/admin) and all /actions requests. It strips cookies from cacheable responses and supports xkey tag-based purging and ESI. The default Time to Live (TTL) is 3 hours, with 6 hours of grace so stale pages can be served if the backend is busy.
  • Cache warming - the platform crawls your site with wget (two levels deep, images excluded) immediately after a deploy and then every 6 hours via cron. This ensures visitors are served cached pages instead of triggering cold rebuilds.
  • App directory - a dedicated craftcms/ directory is created under your app root for the Craft codebase, with storage/ for runtime data, caches and logs.
  • Log handling - Craft rotates its own logs under storage/logs/, so the platform leaves log rotation to the application.

Combine Craft's vendor guidance with the TurboStack options below. Most services can be enabled on the host's Services tab.

  • Keep Varnish enabled - full-page caching is the biggest time-to-first-byte win for content sites; keep it on in production.
  • Enable Redis for Craft's data cache and sessions instead of file or database storage, so cache reads and session lookups stay fast under load.
  • Use a static page cache - Craft's Blitz plugin pairs well with the Nginx config (the 50main.conf already includes a commented cache_path block ready for Blitz).
  • Enable OPcache in the PHP runtime to cut PHP parsing overhead on every request.
  • Run in production config - disable devMode, enable template caching, and deploy a compiled config/project/ so the control panel runs read-only in production.
  • Optimize images - ensure the GD Graphics Library or ImageMagick is available and serve WebP/optimized transforms; offload web/ assets to a Content Delivery Network (CDN) where possible.
  • Add an HTTP cache / CDN in front for static asset delivery; this complements Varnish rather than replacing it.
  • Let the queue run - long tasks (image transforms, search indexing, emails) are processed through Craft's queue. Drive it reliably by running Craft's queue runner as a user system service instead of relying on web-triggered runs.

Sizing and scaling

TurboStack auto-tunes resource limits from the host's size, so start with the defaults. Override the tuning variables only when you have measured evidence (slow queries, cache evictions, a low page-cache hit ratio):

Variable Tune when
mysql_innodb_size The InnoDB buffer pool is too small for your content volume
redis_memory Redis is evicting keys under load
varnish_cache_size The page-cache hit ratio is low because the cache is too small

See Performance tuning before changing any of these. When a single host can no longer keep up, scale up the host before splitting services.

Stability

  • Back up regularly - verify scheduled Backups cover the database, your config/ (including project/), and the storage/ and asset directories.
  • Watch Health - monitor CPU, memory, and disk; Craft's storage/ (runtime caches and logs) grows over time.
  • Keep versions current - track Craft and plugin releases and the PHP and MySQL versions you run.
  • Test on a staging clone - always trial upgrades, plugins, and project config changes on a copy before publishing to production.