
Drupal performance work is concrete. It is specific Drush commands, specific contrib modules, specific configuration changes in settings.php, specific monitoring queries against the database. The conceptual framing matters, but execution is what produces measurable improvement. This post is the practitioner's guide for institutional Drupal teams ready to act on performance, complementing the layered architecture in 10 Tips to Improve Drupal Website Performance and the cache mechanics in Drupal Cache Mechanics.
Diagnostic Tools
Before changing configuration, measure. The diagnostic tools that institutional Drupal teams actually use:
Drush state:get system.performance.css.preprocess and similar commands. Quick checks of the performance-related state values without navigating the admin UI.
Drush watchdog:show. Recent log entries to identify errors or warnings that are happening repeatedly. Performance issues frequently surface as PHP warnings or notices in the log.
XHProf or Tideways for PHP profiling. When the site is slow but the cause is unclear, profiling produces a flame graph showing where time is actually spent. For institutional Drupal, profiling is the right move when the obvious tuning has not produced results.
MySQL slow query log. Enable in MySQL configuration, set long_query_time = 1 for institutional Drupal, review the log for queries over the threshold. Slow queries are often the bottleneck and are usually caused by specific contrib modules or theme code.
Drupal SQL Logger contrib module. Logs every SQL query executed during a request. Useful for identifying excessive query counts in specific code paths.
Lighthouse CI in continuous integration. Synthetic performance regression catching before changes reach production.
New Relic, Datadog, or AWS CloudWatch RUM. Production observability for measuring real-user performance. Institutional Drupal benefits from at least one of these.
Caching Configuration That Matters
Drupal caching configuration in settings.php is the difference between caching working and caching being configured-but-broken.
Use Redis or Memcached as the cache backend. Add the redis or memcache module, configure in settings.php:
$settings['cache']['default'] = 'cache.backend.redis';
$settings['redis.connection']['host'] = 'redis-host';
$settings['redis.connection']['port'] = 6379;
The default database cache backend is the slowest option. Redis is the institutional default.
Set internal page cache TTL appropriately. In admin/config/development/performance, the "Browser and proxy cache maximum age" setting controls page cache TTL. For most institutional Drupal sites, 15 minutes to 1 hour is appropriate. Authenticated traffic bypasses this anyway.
Enable BigPipe. Drupal core's BigPipe module streams cacheable content first and personalized content later in the same response. Enable for authenticated users; the perceived load time improves substantially.
Disable Drupal's internal page cache if Varnish is in front. When Varnish (or a CDN with similar capability) is doing page caching, Drupal's internal page cache is redundant. Disable to save the PHP execution overhead on cache hits that Varnish would have caught.
Configure cache tags for custom code. In any custom module that emits render arrays, declare cache tags in the cache metadata. Tags that are too broad cause excessive invalidation; tags that are missing cause uncacheable surfaces.
Database Discipline
Database tier discipline produces sustained gains.
Enable InnoDB and size the buffer pool. For institutional Drupal, the InnoDB buffer pool should hold the database working set. For a typical institutional site with 5-20 GB database, 8-16 GB buffer pool. Set innodb_buffer_pool_size in MySQL configuration.
Periodic OPTIMIZE TABLE on growing tables. Tables like node_revision, watchdog, cache_*, and key_value grow over time. Periodic OPTIMIZE TABLE reclaims space and improves query performance.
Limit revisions. In admin/structure/types/manage/[type], set revision limits per content type. Unbounded revision growth produces large node_revision tables that affect query performance.
Truncate watchdog if not used. If institutional logging happens through a centralized log aggregator (CloudWatch, ELK, Datadog), the watchdog table may not need to grow. Configure log retention or truncate periodically.
Clean expired transients. Drupal's key_value_expire table accumulates expired transients. Cron should clean them, but verification is part of discipline.
Asset Pipeline Configuration
Drupal's asset pipeline produces gains when configured beyond defaults.
Enable CSS and JS aggregation in production. In admin/config/development/performance, enable both. Performance gains are real even with HTTP/2 because aggregation reduces parse and execution overhead.
Enable Advanced CSS/JS Aggregation (AdvAgg). The AdvAgg contrib module produces additional gains over Drupal core's default aggregation: critical CSS inlining, async JS loading, smarter aggregation grouping.
Use the Image API and image styles. Original-resolution images are rarely the right output size. Image styles produce appropriately-sized derivatives served to the browser. Configure responsive image styles for different viewport sizes.
Add WebP delivery. The WebP module produces WebP versions of images and serves them to supporting browsers. Reduces bandwidth substantially.
Configure font loading. font-display: swap for institutional brand fonts to avoid blank-text periods during load. Subset fonts to actual character set used.
Monitoring and Cadence
The discipline that catches regression:
Set performance budget in continuous integration. Lighthouse CI configured with thresholds for LCP, INP, CLS. Build fails if thresholds are missed.
Review the slow query log on cadence. Weekly or monthly review of slow queries with elimination as the goal.
Track CDN cache hit rate. Cache hit rate dropping is an early signal of cache invalidation issues or cache configuration drift.
Monitor TTFB for cache misses. Origin response time on cache-miss requests reveals when the underlying Drupal stack is slowing down.
Document the performance baseline. Quarterly snapshot of representative metrics. Trends over time show whether the institution is moving forward, holding steady, or regressing.
For managed Drupal hosting engagements supporting institutional Drupal workloads, the practitioner's discipline is part of the engagement scope.
Frequently Asked Questions
What is the single most impactful Drupal performance change for most institutional sites?
For sites without persistent cache backend: switching from database cache to Redis. The lift is typically 40 to 70 percent improvement in cache-related operations. For sites with Redis already configured: it is usually slow query elimination. The specific bottleneck depends on the site profile.
How often should institutional Drupal teams run profiling?
For sites with mature performance posture: opportunistically, when performance regression is suspected or after major code changes. For sites without mature posture: as a baseline activity, quarterly. The profiling produces the ranked list of optimization opportunities.
Should institutional Drupal use AdvAgg or Drupal core's default aggregation?
For institutional sites with performance requirements, AdvAgg produces measurably better results than core defaults. The configuration overhead is small. For sites where performance is not a stated requirement, core defaults are adequate.
How does this compare to WordPress performance work?
Both platforms benefit from similar disciplines. The Drupal-specific tooling (Drush, the cache tag system, contrib modules like AdvAgg) differs from WordPress equivalents. We covered the WordPress practitioner's view in Beyond Basics: Mastering Advanced WordPress Optimization.