Getting started
Basics
Domains & Origins
Performance

Configuration
Basics
Conditions
Dictionaries
Domains & Origins
Request settings
Cache settings
Headers
Responses
Performance
Purging
Custom VCL
Image optimization
Video

Security
Access Control Lists
Monitoring and testing
Securing communications
Security measures
TLS
Web Application Firewall

Integrations
Logging endpoints
Non-Fastly services

Diagnostics
Streaming logs
Debugging techniques
Common errors

Account info
Account management
Billing
User access and control

Reference

    Cache control tutorial

      Last updated December 21, 2018

    You are in full control of how Fastly caches your resources. The most preferred way of instructing Fastly is to use backend HTTP headers. The other way is to use the Varnish Configuration Language (VCL).

    Backend HTTP headers

    You can set four different types of HTTP headers which will have different effects on our caches and on web browsers. If you use more than one type, they are prioritized in the order listed below:

    Surrogate-Control

    Format:

    1
    
    Surrogate-Control: max-age=(time in seconds)
    

    Example:

    1
    
    Surrogate-Control: max-age=3600
    

    will cache something on our caches for one hour. This header gets stripped and is only visible to Fastly caches.

    Cache-Control: s-maxage

    Format:

    1
    
    Cache-Control: s-maxage=(time in seconds)
    

    This is the same as Surrogate-Control, except the header is not stripped and will be respected by Fastly caches and any caches between Fastly and the browser, but not the browser itself.

    Cache-Control: max-age

    Format:

    1
    
    Cache-Control: max-age=(time in seconds)
    

    This header will be respected by Fastly caches, any caches between Fastly and the browser, and the browser itself.

    Expires

    This header caches content until it expires as specified. It will be respected by Fastly caches, any caches between Fastly and the browser and the browser itself. See section 5.3 of RFC7234 for an explanation of the format.

    Do not cache

    If you want to ensure that a resource is not cached by Fastly, send the following HTTP header with the origin response:

    1
    
    Cache-Control: private
    

    If you just set max-age=0 or an Expires in the past, Fastly may still use a single response to satisfy multiple outstanding requests that arrive while waiting on the origin (see Request collapsing), or may cache the object in a stale form so that it can be used in case of errors or asynchronous revaldiation (see Serving stale content).

    The private directive does not prevent content from being cached in the browser. If you need to prevent caching by both Fastly and web browsers, we recommend combining the private directive with max-age=0 or no-store. For example:

    1
    
    Cache-Control: private, no-store
    

    Fastly does not currently respect no-store or no-cache directives. Including either or both of these in a Cache-Control header has no effect on Fastly's caching decision, unless you alter this behavior using custom VCL.

    Applying different cache rules for Fastly and browsers

    Say you want Fastly to cache your content but you don't want it cached by browsers. The best way to do this would be to send Fastly both the Cache-Control header as you want it to go to the browsers, and use Surrogate-Control to tell us how long to cache for. For example:

    1
    2
    
    Cache-Control: no-store, must-revalidate
    Surrogate-Control: max-age=3600
    

    Except for when the Cache-Control header is set to private, the Surrogate-Control header takes priority over Cache-Control, but unlike Cache-Control it is stripped so the browsers don't see it.

    Apache Config

    If you are using Apache, the easiest way to add headers is to use the mod_expires module. For example, to cache GIF images for 75 minutes after the image was last accessed by the cache server, you would add a directive like this under the VirtualHost (or globally). For example:

    1
    2
    
    ExpiresActive On
    ExpiresByType image/gif "access plus 1 hours 15 minutes"
    

    You can also cache whole URL subtrees. For example:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    <Location "/css">
      ExpiresActive On
      ExpiresDefault "access plus 1 year"
    </Location>
    
    <Location "/static/">
      ExpiresActive On
      ExpiresDefault "access plus 1 day"
    </Location>
    

    NGINX Configuration

    To configure NGINX, add the expires directive. For example:

    1
    2
    3
    
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
       expires 1h;
    }
    

    Alternatively, if you need more flexibility in modifying headers you can try the HttpHeadersMore Module.

    Amazon S3 configuration

    By default, S3 doesn't have a facility for setting Cache-Control headers across multiple objects, so you will have to do this file-by-file using the S3Explorer, or in an automated fashion by using a cloud library like boto. Remember that you can combine long cache time with instant purges to enhance your performance.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    from boto.s3.connection import S3Connection
    
    connection = S3Connection('aws access key', 'aws secret key')
    
    buckets = connection.get_all_buckets()
    
    for bucket in buckets:
        for key in bucket.list():
            print('%s' % key)
    
            if key.name.endswith('.jpg'):
                contentType = 'image/jpeg'
            elif key.name.endswith('.png'):
                contentType = 'image/png'
            else:
                continue
    
            key.metadata.update({
                'Content-Type': contentType,
                'Cache-Control': 'max-age=864000'
            })
            key.copy(
                key.bucket.name,
                key.name,
                key.metadata,
                preserve_acl=True
            )
    

    Custom Headers in Programming Languages and Frameworks

    PHP

    More information: https://php.net/manual/en/function.header.php

    Example: add this to your PHP code before you send any output to cache certain HTML for an hour

    1
    
    header('Cache-Control: max-age=3600');
    

    Django

    More information: https://docs.djangoproject.com/en/dev/ref/request-response/#setting-headers

    Example:

    1
    2
    
    response = HttpResponse()
    response['Cache-Control'] = 'max-age=3600'
    

    Sinatra

    More information: http://sinatrarb.com/documentation.html

    Example:

    1
    2
    3
    
    get '/' do
        headers['Cache-Control'] = 'max-age=3600'
    end
    
    Back to Top