Implementing If-Modified-Since

For static content, the expires headers are set by default in MageStack. They can be overridden using either the native Nginx expires directive, or the more powerful $magestack_cache_lifetime (see Controlling Varnish cacheable content. For dynamic content, this is not so consistent, as Nginx will not set any expires directives, as to respect the headers sent by PHP.

Advanced Configuration

The headers must be correctly set at the application level. With Magento, this could easily be leveraged on pages by using the getUpdatedAt() method, but thought should be given to how this is implemented.

Changes made at a single product level in theory would only affect a given product page, however, thought must be given to where that product detail change could also be displayed. For example, a product price change should both be reflected on the product page, but also anywhere else that product may be displayed on the site; be it category pages, other product pages (as a related/upsell), search results etc.

Easy Configuration

Alternatively, if you are already using MageStack Varnish, you can utilise the special $magestack_last_modified variable,

set $magestack_last_modified true;

This will set the last modified header to match that of the time the URL is first cached. This will mean that as long as the asset is cached in Varnish, the header will match the time it "entered" the cache. Should the cache be purged, the header will naturally change to reflect the time of the purge and send the new timestamp.

Using the $magestack_last_modified variable is a simple and effective means to attach the important Last-Modified header to dynamic content, whilst still respecting the recency of the content.

Notes

However, when using the "Easy Configuration" you must bear in mind that it cannot account for is whether the content in the cache (having previously been purged) is identical to the previously cached content and thus technically the previous Last-Modified header should still be respected. This is a shortcoming in the easy approach, but certainly not a negative over not using the header altogether.