Shielding

When Fastly makes requests to your origin servers, those requests may come from any of our data centers, which act independently. However, if you wish, you may designate one data center location as a 'shield', collecting requests from across the Fastly network. In this arrangement, requests to your origin server will come only from the designated shield data center, and all other Fastly locations will forward requests to the shield.

Shielding illustration

Shielding has significant benefits:

  • Reduces origin load: reduces the volume of requests from Fastly to your origin servers
  • Improves cache hit ratio: increases the probability of end user requests resulting in a cache HIT (albeit potentially not from the first data center which handles the request)
  • Speeds up connections: reduces connection setup latency for MISS and PASS requests that must be served from origin.

The latter of these is somewhat counter-intuitive, but takes advantage of the fact that all Fastly data centers always have a pool of open connections to all other Fastly data centers, over highly optimized routes. Minimizing the amount of physical distance to cover outside of the Fastly network reduces the time required for costly multi-roundtrip handshakes.

Enabling and disabling shielding

Shielding may be enabled when adding or editing an origin server, and may be selected per-origin. If your origin servers are in different locations, it may make sense to choose different shields for each origin server. You can enable shielding via the web interface, or set the shield property of a Backend object when you create or modify it using the API or CLI. For example:

$ fastly backend create --name=app_server --address=192.168.123.123 --shield=amsterdam-nl --service-id=9yqrXWr5kfqroswtmxgQDz --version=1
SUCCESS: Created backend app_server (service 9yqrXWr5kfqroswtmxgQDz version 1)

Each data center has a shield identifier. These are listed in the datacenter properties from the /datacenters API endpoint. For example, our data center in Amsterdam has the name AMS but a shield identifier of amsterdam-nl. If you are using a cloud provider, see choosing a shield location.

Effects of shielding

Enabling shielding on a Fastly service will create side effects that should be considered carefully.

Double execution

Services using shielding will (in most cases) execute twice: once at the edge location and once at the shield location. However, if a request is received directly at the shield location, then it will send requests directly to your origin, so the configuration will only execute once.

In VCL, the fastly.ff.visits_this_service variable is the best mechanism available to detect whether the data center processing a request is acting as an edge or a shield. Additionally, you can use the following variables to determine whether the currently assigned backend is a customer origin or a Fastly shield data center:

So, for example, if req.backend.is_origin is true, then if Fastly makes a backend request, it will go to your origin server. This doesn't necessarily mean that the request has already passed through an edge data center, since the end user may have made their request directly to the data center designated as the shield location.

Be aware that changes made to a response at a shield data center will be viewed by an edge data center as if they are part of the response from the origin. Therefore any changes you want to make to a response just before serving it to the browser should be done only on the edge.

In general, operations performed on the request should generally be done at the edge, and operations performed on the response should happen at the shield. Here is a list of some of the most common operations performed in Fastly services and an indication of where these should normally be done in a shielded configuration:

Best done at the edgeBest done at the shield
Manipulating the request URL
Normalizing the request
Authentication
Security filtering (eg WAF or bot detection)
Redirects
Geolocation
A/B testing
ESI
Compressing responses
Setting backend-specific headers

HINT: Rather than detecting the execution location, consider writing your code in a way that is idempotent, that is, it only has effect once, and if you run it again, nothing happens.

For example, static object store origins like S3 or GCS may require a path prefix to be added to the URL. Doing this unconditionally may result in the prefix being added twice, e.g. /bucket-name/bucket-name/path/to/file. While you could use a variable such as fastly.ff.visits_this_service to avoid this, a better solution is to detect the presence of the prefix:

if (req.url.path !~ "^/bucket-name/") {
set req.url = "/bucket-name/" + req.url;
}

Origin definition

For VCL services, it is possible to define backends using VCL code as well as creating a configuration object via the web interface, API or CLI. However, shielding is deployed by generating a large director in your configuration, and generating logic in vcl_recv that will select that director if the data center is not the one identified as the shield. While you could write the vcl_recv logic yourself, you cannot generate the director definition because servers are regularly added and removed from the Fastly network, and when this happens, your shield director will be regenerated. Therefore you cannot apply shielding to origins that you define in VCL.

Host header manipulation

Fastly uses the HTTP Host header on inbound requests to select the correct service to handle the request. If the Host header doesn't match to a known customer domain a 500 Internal Server Error is served to the end user.

If you change the value of req.http.host as part of your configuration and it executes at the edge data center, then be aware that it may be used for service selection at the shield data center. Either manipulate the Host header only at the shield data center (see fastly.ff.visits_this_service) or when a fetch is going to your origin (see req.backend.is_origin), or use the override_host property when creating the backend. The latter option is often the most conceptually straightforward and least prone to error.

Client IP

Requests made from an edge data center to a shield will report the edge data center as the client.ip. To reliably access the true client IP, use the Fastly-provided Fastly-Client-IP header. The client.identity variable is also influenced by the apparent client IP, so if making use of client directors, client.identity should be reset to Fastly-Client-IP or to an identifier specific to your service.

Limitations and constraints

Please be aware of the following when using shielding on your service:

Cache hit ratio inaccuracy

If a request results in a MISS at an edge location and is forwarded to a shield where it finds a HIT, the user is ultimately served from cache, but we will record both the miss and the hit for the purpose of calculating your cache hit ratio. While 'shield hits' will involve more latency for end users than 'edge hits', the hit will still mean there is no need for an origin request. Equally, a request that does reach your origin server will be counted as two misses, one at the edge, and one at the shield.

This will result in a cache hit ratio that may be lower than you expect. Since there are multiple ways of calculating CHR on shielded configurations, you may like to use our historical stats API to get raw numbers and perform your own calculations.

Backend selection

The process of assigning a backend to a request normally happens in the vcl_recv stage of the VCL request lifecycle. For shielded backends, Fastly will insert logic into the #FASTLY recv macro that detects where the backend is set to the shielded backend, and change it to the shield if the current data center is not the designated shield location for that backend.

As a result, if you are using custom VCL and you set the value of req.backend after the #FASTLY recv macro, you will override shielding. Instead, consider performing your backend selection before #FASTLY recv. If you have to do backend selection after the Fastly recv macro has run, you will need to also implement the logic to assign the shield backend where appropriate.

If you use VCL but only via VCL snippets, these are rendered as part of the #FASTLY recv macro and placed before shielding logic, so this is a safe place to perform backend allocation without affecting shielding.

Billing implications

Traffic from one Fastly data center to another will count towards your request count and billable bandwidth. If your service is configured to PASS all traffic, then your request count and delivery bandwidth will almost double, since most requests will be presented to two Fastly data centers, but in more realistic scenarios, shielding will often reduce costs overall. See our guide in documentation for more information.

Examples

Prevent caching in the browser (but not at the edge!):

sub vcl_deliver { ... }
Fastly VCL
if (fastly.ff.visits_this_service == 0) {
set resp.http.Cache-Control = "no-store, private";
}

Reset client.identity to Fastly-Client-IP when using client directors

sub vcl_recv { ... }
Fastly VCL
set client.identity = req.http.Fastly-Client-IP;

Set a host header, but only if the backend is the real origin:

sub vcl_miss { ... }
Fastly VCL
if (req.backend.is_origin) {
set req.http.host = "example.com";
}

Advanced shielding scenarios

Shielding can be used in many different configurations and variations. Some of the most common include:

Multiple origins

In many cases, when a service has multiple origins, they are in the same place and benefit from the same shield location. However, if you have multiple origin locations (for example because you have origins serving different regions), then each origin may benefit from having a distinct shield location.

Multiple origins

This is supported without additional VCL. Choose the shield location that is most appropriate for each origin, and configure the shield property to your chosen shield identifier.

Sharded shields

In a sharded shielding configuration, two or more data centers are used as a shield tier for a single origin, with requests allocated to shields based on content hash. In this way, the two shield locations each maintain half of your cache. This mechanism makes use of custom directors, which operate on top of the automatically generated directors created by Fastly.

Sharded shield illustration

Sharded shielding requires bespoke implementation in VCL. The following example demonstrates the solution using the BWI and DCA data centers, which are close together, and will allocate approximately half of your site's URLs to one and half to the other. Requests received directly on one of the shields will be passed to the other if it is the intended shield for the URL requested, otherwise will go directly to origin.

director multi_shield_director chash {
{ .backend = shield_bwi_va_us; .id = "bwi"; .weight = 100; }
{ .backend = shield_dca_dc_us; .id = "dca"; .weight = 100; }
}
director multi_shield_director_when_bwi chash {
{ .backend = F_Shielded_Origin; .id = "bwi"; .weight = 100; }
{ .backend = shield_dca_dc_us; .id = "dca"; .weight = 100; }
}
director multi_shield_director_when_dca chash {
{ .backend = shield_bwi_va_us; .id = "bwi"; .weight = 100; }
{ .backend = F_Shielded_Origin; .id = "dca"; .weight = 100; }
}
sub vcl_recv {
#FASTLY recv
if (req.backend == F_Shielded_Origin && req.restarts == 0) {
if (server.datacenter ~ "^(BWI|DCA)$" && fastly.ff.visits_this_service > 0) {
set req.backend = F_Shielded_Origin;
} else {
if (server.datacenter == "BWI") {
set req.backend = multi_shield_director_when_bwi;
} elseif (server.datacenter == "DCA") {
set req.backend = multi_shield_director_when_dca;
} else {
set req.backend = multi_shield_director;
}
}
}
}

Choosing a shield location

Some cloud providers have locations that interconnect with Fastly, so if this applies to you, please choose a shield location where we have an interconnect, for optimal performance:

Amazon AWS locations

AWS regionNameRecommended Fastly data centerShield code
us-east-1US East (N. Virginia)DCA (Ashburn)dca-dc-us
us-east-2US East (Ohio)CHIchi-il-us
us-west-1US West (N. California)PAOpao-ca-us
us-west-2US West (Oregon)SEAsea-wa-us
ap-northeast-1Asia Pacific (Tokyo)HNDhnd-tokyo-jp
ap-northeast-2Asia Pacific (Seoul)HNDhnd-tokyo-jp
ap-northeast-3Asia Pacific (Osaka-Local)ITMosaka-jp
ap-south-1Asia Pacific (Mumbai)SINsingapore-sg
ap-southeast-1Asia Pacific (Singapore)SINsingapore-sg
ap-southeast-2Asia Pacific (Sydney)SYDsydney-au
ca-central-1Canada (Central)YYZyyz-on-ca
cn-north-1China (Beijing)HKGhongkong-hk
cn-northwest-1China (Ningxia)HKGhongkong-hk
eu-central-1EU (Frankfurt)FRAfrankfurt-de
eu-west-1EU (Ireland)LHRlondon-uk
eu-west-2EU (London)LHRlondon-uk
eu-west-3EU (Paris)CDGcdg-par-fr
eu-north-1EU (Stockholm)BMAstockholm-bma
sa-east-1South America (Sao Paulo)GRUgru-br-sa
us-gov-east-1AWS GovCloud (US-East)DCAdca-dc-us
us-gov-west-1AWS GovCloud (US)SEAsea-wa-us

Google Cloud platform locations

GCP regionNameRecommended Fastly data centerShield code
asia-east1Changhua County, TaiwanHKGhongkong-hk
asia-east2Hong KongHKGhongkong-hk
asia-northeast1Tokyo, JapanHNDhnd-tokyo-jp
asia-northeast2Osaka, JapanHNDhnd-tokyo-jp
asia-south1Mumbai, IndiaSINsingapore-sg
asia-southeast1Jurong West, SingaporeSINsingapore-sg
australia-southeast1Sydney, AustraliaSYDsydney-au
europe-north1Hamina, FinlandHELhel-helsinki-fi
europe-west1St. Ghislain, BelgiumAMSamsterdam-nl
europe-west2London, England, UKLHRlondon-uk
europe-west3Frankfurt, GermanyFRAfrankfurt-de
europe-west4Eemshaven, NetherlandsAMSamsterdam-nl
europe-west6Zürich, SwitzerlandFRAfrankfurt-de
northamerica-northeast1Montréal, Québec, CanadaYYZyyz-on-ca
southamerica-east1São Paulo, BrazilGRUgru-br-sa
us-central1Council Bluffs, Iowa, USAMDWmdw-il-us
us-east1Moncks Corner, South Carolina, USAATLatl-ga-us
us-east4Ashburn, Northern Virginia, USADCAdca-dc-us
us-west1The Dalles, Oregon, USASEAsea-wa-us
us-west2Los Angeles, California, USABURbur-ca-us

User contributed notes

We welcome comments that add use cases, ideas, tips, and caveats. All comments will be moderated before publication. To post support questions, visit our support center and we'll find you the help you need.