Customizing the Page Cache Key

The page cache key defines what makes a unique entry in the page cache. By default, SpinupWP uses the following as the page cache key:

$scheme$request_method$http_host$request_uri

For example, a request for https://tunipjuicemedia.com/team/ would yield the following cache key:

httpsGETtunipjuicemedia.com/team/

There are lots of reasons why you might want to customize the page cache key. Although we don’t recommend this, one of our customers caches mobile and desktop requests separately.

To accomplish this, they first do some user agent sniffing (again, we don’t recommend this as it is not reliable) to set a custom $request_mobile variable by adding the following snippet to their nginx.conf:

map $http_user_agent $is_mobile {
    "~*(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino"  mobile;
    "~*^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-)"  mobile;
   default  desktop;
}

Then they update the /etc/nginx/sites-available/{domain}/server/fastcgi-cache.conf Nginx config file for each site with the following cache key:

fastcgi_cache_key "$scheme$request_method$host$request_uri$is_mobile";

To make their WordPress site aware of the different cache key and enable the “Purge this URL” feature to work, they add the following snippet to a WordPress plugin:

add_filter('spinupwp_cache_key_for_url', function($cache_keys, $url) {
  $parsed_url = parse_url( trailingslashit( $url ) );
  return array(
    $parsed_url['scheme'] . 'GET' . $parsed_url['host'] . $parsed_url['path'] . 'desktop',
    $parsed_url['scheme'] . 'GET' . $parsed_url['host'] . $parsed_url['path'] . 'mobile'
  );

}, 10, 2);

Although the page cache key includes $request_method and $request_uri (which includes the query string), there are if statements in fastcgi-cache.conf that skip the page cache entirely for POST requests and requests containing a query string, so cache keys will never contain POST or a query string.

So, why include them in the cache key?

Well, you may want to make the caching more aggressive. For example, you could comment out the if statement that skips the cache for requests containing a query string. And since we’re using $request_uri already, you don’t need to update the page cache key.

Warning: If you do comment out the if statement that skips the cache for requests containing a query string, beware that you could greatly increase the number of cache entries and possibly DDoS yourself. For example, email marketing apps often add a unique query string to each URL in your emails, which would result in a separate cache entry for every person who clicks through from one of your emails.