Loading...


Related Products


Date Published: April 22, 2025

Using custom Vary headers to create variations in Varnish cache

If you have a website that you want to be able to cache different versions for country, region or city, and you also do not want to run custom VCL due to the multiple pain points this imposes, but you also want simple purging with Acquia Purge, consider using custom Vary headers for caching and purging purposes.

Vary header to the rescue

The Vary header is sent by the web server to indicate what makes a HTTP object Vary. This makes a lot of sense with headers like Accept-Encoding. When a server issues a Vary: Accept-Encoding it tells Varnish that its needs to cache a separate version for every different Accept-Encoding that is coming from the client. If a client only accepts gzip encoding, Varnish won't serve the version of the page encoded with the Deflate encoding.

Warning!

Acquia Edge does not respect the "Vary" header! You will not be able use this article with it!

How to use a custom Vary header

If you are using a CDN then you can get these CDN providers to include an extra HTTP header on all requests back to Acquia. You can also add additional custom Vary headers in the response from Drupal. Make sure that your CDN supports the Vary header!

For Drupal 7

See drupal_add_http_header on the Drupal API. Here is an example that varies on X-MYCUSTOMHEADER header:

/**
 * Implements hook_page_build().
 */
function MYMODULE_page_build(&$page) {
  drupal_add_http_header('Vary', 'X-MYCUSTOMHEADER', TRUE);
}

For Drupal 8

  • Custom Module

In Drupal 8 use public function HttpResponse::setHeader along with an event subscriber. Below you can find an example class and services.yml. For a more detailed example please see Event Systems Overview & How To Subscribe To and Dispatch Events.

Warning

Please make sure to replace mymodule_event_subscriber and MyEventSubscriber in your own implementation

  • mymodule_event_subscriber.services.yml
services:
  mymodule_event_subscriber:
  class: '\Drupal\mymodule_event_subscriber\EventSubscriber\MyVaryEventSubscriber'
  tags:
    - { name: 'event_subscriber' }
  • /EventSubscriber/MyVaryEventSubscriber.php
namespace Drupal\mymodule_event_subscriber\EventSubscriber;

use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
  * Class MyVaryEventSubscriber
  */
class MyVaryEventSubscriber implements EventSubscriberInterface {

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events['kernel.response'] = ['onRespond'];

    return $events;
  }

  /**
   * This method is called when the kernel.response is dispatched.
   *
   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
   *   The dispatched event.
   */
  public function onRespond(FilterResponseEvent $event) {
    $response = $event->getResponse();
    $response->headers->set('Vary', 'X-MYCUSTOMHEADER');
  }
}
  • Contrib Module

The module HTTP Response Headers can also be used to set the Vary header

How to purge all variants in Varnish for a particular URL

Acquia's stock VCL (Varnish Configuration Language) in Acquia Cloud means that if a PURGE request hits (e.g. it matches a variant in cache), or misses (not in cache), purge is still called. This means all variants will be removed from Varnish immediately. You can also use Acquia Purge.

Known Issues

Warning

Drupal 9 page cache does not respect the Vary header, please ensure that you read Drupal 9 page cache does not respect the Vary header.

Warning

Drupal 7 page cache does not respect the Vary header, please ensure that you read Drupal 7 page cache does not respect the Vary header.

You need to ensure that Drupal is not caching pages for anonymous users (as it will not cache per variant, causing much frustration). See above warnings! 

You will also need to be running Acquia's stock VCL with no changes to the vcl_hash() function (e.g. using geo_ip functionality), as any alterations to this function will cause a regular PURGE to not remove all variants.

Did not find what you were looking for?

If this content did not answer your questions, try searching or contacting our support team for further assistance.

Back to Section navigation