Basics
- About the web interface controls
- Always-on DDoS mitigation
- Browser recommendations when using the Fastly web interface
- Content and its delivery
- Fastly POP locations
- Getting started with Fastly
- How caching and CDNs work
- How Fastly's CDN Service works
- HTTP status codes cached by default
- Self-provisioned Fastly services
- Sign up and create your first service
- Working with services
Domains & Origins
Performance
Basics
Dictionaries
Domains & Origins
- Changing origins based on user location
- Connecting to origins
- Enabling global POPs
- Failover configuration
- IPv6 support
- Maintaining separate HTTP and HTTPS requests to origin servers
- Routing assets to different origins
- Setting up redundant origin servers
- Specifying an override host
- Using Fastly with apex domains
Request settings
Cache settings
Headers
Responses
Performance
- About Dynamic Servers
- Cache control tutorial
- Caching configuration best practices
- Controlling caching
- Creating and using pools with Dynamic Servers
- Creating and using server entries with Dynamic Servers
- Enabling API caching
- Enabling automatic gzipping
- Failure modes with large files
- HTTP/2 server push
- Implementing API cache control
- Making query strings agnostic
- Request collapsing
- Segmented Caching
- Serving stale content
- Setting Surrogate-Key headers based on a URL
- Setting Surrogate-Key headers for Amazon S3 origins
- Streaming Miss
Purging
Custom VCL
- Accept-Language header VCL features
- Authenticating before returning a request
- Basic authentication
- Creating location-based tagging
- Custom responses that don't hit origin servers
- Delivering different content to different devices
- Enabling URL token validation
- Guide to VCL
- Isolating header values without regular expressions
- Manipulating the cache key
- IP geolocation variables: Migrating to the new dataset
- Overriding which IP address the geolocation features use
- Response Cookie handling
- Support for the Edge-Control header
- Understanding the different PASS action behaviors
- Using edge side includes (ESI)
- VCL regular expression cheat sheet
Image optimization
Video
Access Control Lists
Monitoring and testing
Securing communications
Security measures
TLS
- Domain validation for TLS certificates
- Enabling HSTS through Fastly
- Forcing a TLS redirect
- Managing domains on TLS certificates
- Serving HTTPS traffic using certificates you manage
- Serving HTTPS traffic using Fastly-managed certificates
- Setting up free TLS
- TLS key and certificate replacement
- TLS termination
Web Application Firewall
Logging endpoints
- Log streaming: Amazon S3
- Log streaming: Microsoft Azure Blob Storage
- Log streaming: Cloud Files
- Log streaming: Datadog
- Log streaming: DigitalOcean Spaces
- Log streaming: Elasticsearch
- Log streaming: FTP
- Log streaming: Google BigQuery
- Log streaming: Google Cloud Storage
- Log streaming: Honeycomb
- Log streaming: Kafka
- Log streaming: Log Shuttle
- Log streaming: LogDNA
- Log streaming: Logentries
- Log streaming: Loggly
- Log streaming: Heroku's Logplex
- Log streaming: OpenStack
- Log streaming: Papertrail
- Log streaming: Scalyr
- Log streaming: SFTP
- Log streaming: Splunk
- Log streaming: Sumo Logic
- Log streaming: Syslog
Non-Fastly services
Streaming logs
Debugging techniques
Common errors
Account management
Billing
User access and control
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.
Configuring popular web servers
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.
TIP: While it's difficult to get S3 to set Surrogate-Control
, you can set x-amz-meta-surrogate-control
instead on origin and Fastly will honor that.
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
)
IMPORTANT: The above example provides an S3 configuration option for customers with small- to medium-sized buckets. However, it iterates over every object in those buckets. If you have millions of objects this may not be the right approach. For millions of objects, we recommend using VCL. Be sure to contact us for assistance.
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
TIP: Expiration times in these examples are provided for guidance only. You can use longer expirations coupled with our purging API to make your site faster and your backend less loaded.