Enabled GZIP But You’re Still Serving Uncompressed Objects?


If you’ve recently enabled GZIP, it’s possible that old uncompressed objects are still in the cache—obviously, this is easily remedied by purging those objects.

But that’s not always convenient—you may have too many cached objects without surrogate keys attached to them, making them difficult to track. And doing a purge all may not be best for your backend.

If you want to avoid purging, you can instead use custom vcl to ensure that you’re only serving compressed versions of these objects.

Step 1

In the Fastly boilerplate, you can add something like the block below to vcl_deliver. This will force a restart if the response is uncompressed and its type or extension is among those that you configured to be GZIP’ed.

In this particular example, we’re using req.url.ext ~ "(txt|json)" and obj.http.content-type ~ "(text/plain|text/html").

sub vcl_deliver {
  if (req.http.Accept-Encoding ~ "gzip" && resp.http.Content-Encoding !~ "gzip" && req.restarts == 0) {
 if ( req.url.ext ~ "(txt|json)" || obj.http.content-type ~ "(text/plain|text/html") {
    set req.http.Force-Miss = "true";

Step 2

Next, in vcl_recv, you can add the following logic, which will force a MISS on a restart, making Fastly go to the origin to retrieve a fresh version of the object.

sub vcl_recv {
  if (req.restarts == 0) {
    unset req.http.Force-Miss;

  if (req.http.Force-Miss) {
    set req.hash_always_miss = true;
    set req.http.Fastly-Force-Shield = "true";

As a final note, keep in mind that when uploading custom vcl, make sure you include the entire Fastly boilerplate with your customizations included in it. And feel free to throw your code into a test service first, just to make sure it’s behaving exactly you’d hoped.