Drupal best practices
This page collects the settings and habits that keep a Drupal site fast and stable on TurboStack. Drupal is a configuration-only application on the platform: you bring your own codebase and database and deploy with Git deployment, while TurboStack provisions and tunes the surrounding stack.
Note
Because the code and database are yours, application-level tuning (caching modules, compiled assets, scheduled tasks) is your responsibility. TurboStack handles the runtime, web server, cache, and database layers.
What TurboStack configures for you
When you set an app's type to drupal, the platform provisions and pre-tunes several pieces so you do not have to:
- Nginx vhost tuned for Drupal. A Drupal-aware server config is written to your app's
nginx/50main.conf. It sets the document root topublic_html, routes clean URLs throughindex.php, passes image-style and asset generation back to Drupal, and serves static files with longexpiresheaders. - PHP-FPM backend. Requests for
.php(andupdate.php) are passed to a dedicated PHP-FPM pool for your user/app, with a generousfastcgi_read_timeoutfor long operations like updates and imports. - Security hardening in the vhost. Direct access is denied to PHP in
sites/*/files, scripts undervendor/, and private file paths. Dotfiles (except.well-known) and source files such as.module,.inc,.twig,.yml,composer.json, and*.sqlare also blocked. - Varnish full-page cache (optional). When you enable Varnish, a Drupal-specific VCL is installed. It is built for the Advanced Varnish module: cache-tag and wildcard
BANinvalidation, per-role cache bins via theADVBINcookie, ESI/BigPipe support, gzip compression, and cookie stripping for static assets. Authenticated,/user,/admin, and cron/install/update paths bypass the cache. - Redis service. Redis can be enabled as a service for object and session caching (you must point Drupal at it - see below).
Tip
The vhost is written with force: no, so it is not overwritten on later runs. If you hand-edit nginx/50main.conf, your changes persist - but you then own keeping it current.
Recommended optimizations
Combine Drupal's own production guidance with the platform options. Enable services on the host's Services tab.
- Use Redis for cache and sessions. Enable the Redis service, install the Drupal
rediscontrib module, and configure the cache backends insettings.php. This removes cache and session load from MySQL. SeeRedis object and session cache for the config block and TTL tuning. - Enable Varnish for anonymous traffic. Turn on Varnish and install the Advanced Varnish module so cache-tag invalidation works with the supplied VCL. Anonymous page views are then served without hitting PHP.
- Turn on Drupal's own caches. In production, enable page and dynamic page caching and the internal CSS/JS aggregation; never run with the Twig debug cache disabled.
- Aggregate and compress assets. Enable Cascading Style Sheets (CSS) and JavaScript (JS) aggregation; the Nginx config already serves the compiled files with far-future expiry.
- Keep OPcache warm. PHP OPcache caches compiled code; keep it enabled and sized for your module count to cut per-request overhead.
- Optimize images. Use responsive image styles and modern formats (WebP/AVIF), which the vhost serves with caching.
- Run cron via Drush, not the web cron. Disable Drupal's automated web cron and schedule
drush cronso cron is decoupled from page requests. Use a Scheduled task / cron service on the host. - Use a Content Delivery Network (CDN) in front of the site for static assets and global reach where appropriate.
Redis object and session cache
Enable the Redis service, install the Drupal redis contrib module, then point Drupal at the cache instance over its socket. TurboStack runs the cache instance on port 6379 (socket /var/run/redis/redis.sock) with no password. Add this to settings.php:
$settings['redis.connection']['interface'] = 'PhpRedis';
$settings['redis.connection']['host'] = '/var/run/redis/redis.sock';
$settings['redis.connection']['port'] = 6379;
$settings['redis.connection']['password'] = '';
$settings['redis.connection']['prefix'] = 'example:';
Use a unique prefix per site so several sites on one host do not overwrite each other's keys. Clear all caches after the change (drush cr).
Tune the cache Time to Live (TTL)
The Drupal Redis module gives permanent cache items a long default lifetime. The constant LIFETIME_PERM_DEFAULT in modules/contrib/redis/src/Cache/CacheBase.php is 31536000 (one year): any key without an explicit TTL falls back to that. A one-year fallback lets stale bins build up and fill Redis.
You do not need to edit the module. Set a shorter TTL per cache bin in settings.php with the perm_ttl_<bin> setting:
$settings['redis.settings']['perm_ttl_cache_menu'] = 21600; // 6 hours
This gives the menu bin a six-hour lifetime while other bins keep the default. Add one line per bin you want to cap. To decide which bins matter, inspect the keys (for example with Redis Insight) and sort by TTL, then purge the old keys:
drush cr
tscli redis clear
Warning
tscli redis clear empties the cache Redis instance. Run it only when you intend to clear the cache. The persistent instance on port 6378 (sessions) is not touched.
Sizing and scaling
TurboStack auto-tunes service sizes to the host. Change them only when you have measured evidence (slow queries, cache evictions, memory pressure):
See Performance tuning for how to measure before changing defaults, and increase PHP memory_limit only for genuinely heavy operations (config import, large migrations).
Stability
- Back up before changes. Confirm scheduled Backups cover both the database and
sites/default/files, and take one before deploys ordrush updb/config imports. - Watch Health. Monitor CPU, memory, and service status, especially after a deploy.
- Keep versions current. Track security releases for Drupal core, contrib modules, and the PHP runtime.
- Manage config in Git. Export with
drush cexand import withdrush cimso configuration moves predictably between environments. - Test on a staging clone before applying updates or module changes to production.