
Drupal caching for institutional sites is a multi-layer implementation. Each layer has its own configuration, its own invalidation behavior, and its own role in the request flow. Getting them right requires concrete configuration in settings.php, on the hosting platform, and at the CDN. This post is the practitioner's implementation guide for institutional Drupal teams putting the caching stack in place.
We covered the cache mechanics and theory in Drupal Cache Mechanics and the broader performance pattern in 10 Tips to Improve Drupal Website Performance. This post focuses on the implementation steps.
The Caching Stack to Implement
For institutional Drupal at production scale, the caching stack:
- CDN (CloudFront, Fastly, Cloudflare) at the edge for global asset and HTML delivery
- Varnish (or equivalent) as the reverse-proxy cache between CDN and Drupal
- Drupal page cache for anonymous user HTML caching
- Drupal dynamic page cache for authenticated user partial caching
- Drupal render cache and entity cache for granular component caching
- Cache backend (Redis or Memcached) as the storage layer for all the above
- BigPipe for streaming personalized content alongside cached content
Each layer is implemented in sequence. Skipping a layer reduces the cumulative benefit.
Step 1: Cache Backend (Redis)
Redis is the institutional default cache backend. Install the Redis contrib module, configure in settings.php:
$settings['redis.connection']['host'] = 'redis-host';
$settings['redis.connection']['port'] = 6379;
$settings['cache']['default'] = 'cache.backend.redis';
$settings['cache_prefix'] = 'institutional-site:';
For institutional Drupal on AWS, ElastiCache for Redis is the canonical pattern. For self-hosted, Redis runs on dedicated infrastructure with appropriate memory allocation.
The cache_prefix setting matters when multiple Drupal sites share the same Redis instance: it prevents cross-site cache key collisions.
Step 2: Drupal Internal Caches
In admin/config/development/performance:
- Browser and proxy cache maximum age: 15 minutes for institutional sites with regular content changes; 1 hour for sites with infrequent changes
- Aggregate CSS files: Enabled
- Aggregate JavaScript files: Enabled
In core.extension.yml (or via the admin UI), confirm enabled:
- Internal Dynamic Page Cache: Enabled (caches authenticated traffic at the partial-render level)
- Internal Page Cache: Enabled if no Varnish; disabled if Varnish is in front
- BigPipe: Enabled (streams cacheable content first, personalized content later)
The internal-page-cache decision depends on infrastructure: with Varnish, disable Drupal's internal page cache to save the PHP overhead on cache hits Varnish caught.
Step 3: Varnish (Where Deployed)
For institutional Drupal at production scale, Varnish in front of the Drupal origin reduces origin load substantially. Varnish configuration (VCL):
- Cache anonymous responses by URL plus appropriate headers (Accept, Accept-Encoding)
- Strip cookies on cache lookups for cacheable URLs (Drupal sets cookies broadly; cache-key cleaning matters)
- Honor
Cache-Controlheaders from Drupal (which BigPipe and Internal Dynamic Page Cache set) - Pass authenticated requests directly to Drupal without caching
Drupal's Purge contrib module handles cache invalidation propagation: when Drupal cache tags invalidate, Purge sends purge requests to Varnish. The configuration:
- Install Purge module
- Add the Varnish purger configuration with the Varnish endpoint
- Add the Cache Tags Queuer configuration
- Configure the processor to run on cron or asynchronously
Purge is the bridge between Drupal's surgical cache tag invalidation and Varnish's URL-based cache. Without Purge, Varnish caches stale content after Drupal content changes.
Step 4: CDN
In front of Varnish (or in front of Drupal directly for smaller institutional sites), the CDN handles global distribution and DDoS absorption. Common institutional choices:
CloudFront. AWS-integrated, strong fit for institutional Drupal on AWS. Configure with origin pointing at Varnish or Drupal load balancer.
Cloudflare. DNS-driven, free tier sufficient for many institutional sites. Configure with Drupal origin and appropriate cache rules.
Fastly. Higher-end option with deeper VCL configuration, common for sites with substantial traffic and specific edge requirements.
CDN configuration:
- Cache TTL by content type: long for static assets (months), moderate for HTML (hours), zero for authenticated content
- Cache invalidation via API when content changes (Purge module can extend to CDN purging through additional purgers)
- WAF rules for known attack patterns
- Compression at the edge (Brotli or gzip)
The CDN is the outermost layer; cache hits at the CDN never reach the institutional origin.
Step 5: Cache Tag Discipline in Custom Code
Custom modules and themes need to declare cache tags accurately. Examples:
For a render array that displays node content:
$build['#cache']['tags'] = $node->getCacheTags();
For a render array that varies by user:
$build['#cache']['contexts'][] = 'user';
For a render array that depends on a block configuration:
$build['#cache']['tags'][] = 'config:' . $block->getConfigDependencyName();
The discipline: every render array declares cache metadata. The cache metadata is reviewed in code review.
Step 6: Validation and Monitoring
Once the caching stack is in place, validation:
Check cache hit rate at each layer. CDN hit rate, Varnish hit rate, Drupal cache backend operations. Targets: CDN above 90 percent, Varnish above 85 percent, Drupal cache hit rate high.
Test invalidation propagation. Edit a piece of content, verify the change appears within expected time windows. Test for both authenticated and anonymous users.
Monitor cache backend memory. Redis memory usage, eviction rates. If Redis is constantly evicting, the cache is undersized.
Watch for uncacheable surfaces. Pages with very high origin traffic in proportion to total traffic indicate uncacheable rendering. Investigate the cache metadata on those pages.
What Mature Institutional Drupal Caching Looks Like
Institutional Drupal sites with mature caching: Redis or Memcached as the backend, all Drupal internal caches enabled or appropriately configured, Varnish or equivalent reverse proxy in front, CDN at the edge, cache tag discipline in custom code, Purge module bridging Drupal invalidation to external caches, monitoring on cache hit rates and invalidation behavior.
The cumulative effect: a Drupal request that hits CDN cache returns in milliseconds. A request that misses CDN but hits Varnish returns in tens of milliseconds. A request that misses Varnish but hits Drupal page cache returns in low hundreds. A request that goes all the way to PHP and database is the rare case.
For managed Drupal hosting engagements supporting institutional sites, this caching stack is part of the engagement scope.
Frequently Asked Questions
Is all six layers necessary for every institutional Drupal site?
For larger institutional sites with substantial traffic, yes. For smaller institutional sites (departmental sites, low-traffic public-information sites), the CDN layer plus Drupal's internal caches with Redis backend is often sufficient. The decision depends on traffic profile and operational capacity.
How long does it take to implement the full caching stack?
For an existing institutional Drupal site without proper caching: 2 to 4 weeks of focused work, including Redis setup, Drupal cache configuration, Varnish setup (if applicable), CDN configuration, Purge module configuration, and validation. The work is concrete and bounded.
What is the typical performance lift from implementing the full stack?
For an institutional Drupal site that did not have proper caching: 5x to 50x improvement in measured response time, depending on the starting state. Cache hit rates above 90 percent become achievable. Origin load drops by 70 to 95 percent for typical traffic profiles.
How does this differ from WordPress caching implementation?
Drupal caching is more granular but more complex to configure. WordPress caching is simpler but less surgical. Both produce institutional-grade performance with proper implementation. We covered the WordPress equivalent in Turbocharge WordPress Website Performance.