Movatterモバイル変換


[0]ホーム

URL:


  1. Home
  2. Guides
  3. Core concepts
  4. Edge state and caching
  5. Cache interfaces

HTTP caching semantics

IMPORTANT:The content on this page uses the following versions of Compute SDKs:JavaScript SDK: 3.30.1 (current is 3.37.0, seechanges),Rust SDK: 0.11.6 (current is 0.11.12, seechanges),Go SDK: 1.5.0 (current is 1.6.1, seechanges)

One of the most common uses of the Fastly edge cache is to store HTTP resources, such as webpages, JavaScript, CSS, images, and video. TheHTTP Caching specification describes how to store a response associated with a request and reuse the stored response for subsequent requests.

Fastly'sreadthrough cache interface interprets and processes the instructions encoded into HTTP responses. For example, the most common (and best practice) means of controlling cache lifetime is by setting an appropriateCache-Control header on a backend response.

This page describes the amount of time that HTTP resources are cached, and how you can effectively control the caching behavior.

WARNING: The before-send and after-send callbacks discussed on this page are part ofcustomized readthrough (HTTP) cache behavior. For the Compute JavaScript and Go SDKs, this is an opt-in feature. Seethis note for details.

Response processing

When a response is received from a backend, the readthrough cache interface parses relevant response headers to determine whether it can be cached, and for how long.

  1. CDN services
  2. Compute services

In a VCL service, response processing results can be inspected and overridden during thevcl_fetch subroutine, which is executed once the response has been parsed (unless the request is arevalidation).

Parsing cache controls

HTTP responses are parsed for the following cache semantics:

PropertyParsing logicDefault
Is response cacheable?If the fetch is a result of an earlierexplicit pass on the request, thenno; otherwise
if the fetch is a result of ahit-for-pass, thenno; otherwise
if HTTP status is200,203,300,301,302,404, or410, thenyes;
otherwiseno
N/A
Cache TTLResponse headers in order of preference:
Surrogate-Control: max-age={n}, otherwise
Cache-Control: s-maxage={n}, otherwise
Cache-Control: max-age={n}, otherwise
Expires: {date}
2 min
Stale-while-revalidate TTLResponse headers in order of preference:
Surrogate-Control: stale-while-revalidate={n}, otherwise
Cache-Control: stale-while-revalidate={n}
0
Stale-if-error TTLResponse headers in order of preference:
Surrogate-Control: stale-if-error={n}, otherwise
Cache-Control: stale-if-error={n}
0

For example, anHTTP 200 (OK) response with no cache-freshness indicators in the response headersis cacheable and will have a TTL of 2 minutes. A500 Internal Server Error response withCache-Control: max-age=300 isnot cacheable, because of its HTTP status code, and therefore the 5 minute TTL (300 seconds) indicated in theCache-Control header is irrelevant.

  1. CDN services
  2. Compute services
  3. Rust
  4. JavaScript
  5. Go

In a VCL service, once the response has been parsed, the status code, headers received with the response, and cache controls resulting from parsing the response headers are available as VCL variables duringvcl_fetch:

Age

A backend can set theAge HTTP response header to indicate that an object has already spent some time in a cacheupstream before being served to Fastly. If the response includes anAge header with a positive value, that value will be subtracted from the response'smax-age, if it has one. If the resulting TTL is negative, it is considered to be zero. If the TTL of a response is derived from anExpires header, anyAge header also present on the response will not affect the TTL calculation.

Age does not affect the initial values ofstale-while-revalidate orstale-if-error TTLs. If a response includes aCache-Control: max-age=60, stale-while-revalidate=300 and alsoAge: 90, then the object's TTL will be set to 0 (becauseAge is higher than 60) but the separatestale-while-revalidate TTL will still be 300 seconds.

  1. CDN services
  2. Compute services

In a VCL service, it's possible to change or remove theAge header on the response during thevcl_fetch subroutine. However, this will not affect the TTL that the object will receive in the cache, as the TTL will have already been calculated by that point.

If you need to modify the TTL, seeoverriding semantics below.

Fastly's readthrough cache interface alsosets theAge header each time it returns a response. Each response receives a new value for theAge header, equal to the amount of time that the object has spent in the Fastly cache, plus (if set) the value of theAge header on the cached object. This mechanism is used to ensure that objects cached in multiple tiers of the Fastly platform as a result ofshielding will not accrue more cache freshness than was originally intended.

  1. CDN services
  2. Compute services

In VCL services, theAge header is set in this way just before the response is delivered to the client.

Surrogate control

TheSurrogate-Control: max-age andCache-Control: s-maxage header directives express a desired TTL forserver-based caches (such as Fastly's readthrough cache). Therefore, these will be given preference overCache-Control: max-age when calculating the initial value of the response object's TTL.

Additionally, Fastly will remove anySurrogate-Control header before a response is sent to an end user. Fastly does not, however, remove thes-maxage directive from anyCache-Control header.

IMPORTANT: If your service usesshielding, then the 'end user' making the request to the Fastly edge may be another FastlyPOP. In this situation Fastlydoes not strip theSurrogate-Control header, so that bothPOPs will parse and respect theSurrogate-Control instructions.

Overriding semantics

  1. CDN services
  2. Compute services
  3. Rust
  4. JavaScript
  5. Go

During thevcl_fetch subroutine, you can affect the caching behavior in a number of ways:

  • Modifying Fastly cache TTL
    To change the amount of time the readthrough cache interface will cache an object, override the value ofberesp.ttl,beresp.stale_while_revalidate, andberesp.stale_if_error:

    setberesp.ttl=300s;

    HINT: This will override entirely the TTL that Fastly has determined by parsing the response's freshness semantics. If your service usesshielding, you may want to subtractAge manually. See theberesp.ttl docs for more information.

  • Modifying downstream (browser) cache TTL
    To change the way that downstream caches (including browsers) treat the resource, override the value of the caching headers attached to the object. Take care if you useshielding since you may also be changing the caching policy of a downstream Fastly cache:

    if (req.backend.is_origin) {
    setberesp.http.Cache-Control="max-age=86400";# Rules for browsers
    setberesp.http.Surrogate-Control="max-age=31536000";# Rules for downstream Fastly caches
    unsetberesp.http.Expires;
    }

The standardVCL boilerplate (which is also included in any Fastly VCL service that does not use custom VCL) applies some logic that affects freshness:

  • If the response has aCache-Control: private header, execute areturn(pass).
  • If the response has aSet-Cookie header, execute areturn(pass).
  • If the response does not have any ofCache-Control: max-age,Cache-Control: s-maxage orSurrogate-Control: max-age headers, setberesp.ttl to thefallback TTL configured for your Fastly service.

WARNING: If you are using custom VCL, the fallback TTL configured via theweb interface orAPI will not be applied, and the fallback TTL will be as hard-coded into your VCL boilerplate (you're free to remove any of the default interventions, including the fallback TTL logic, if you wish)

Cache outcome

  1. CDN services
  2. Compute services
  3. Rust
  4. JavaScript
  5. Go

After parsing the response for freshness information and executing thevcl_fetch subroutine, the readthrough cache decides whether to save the object based on the following criteria, in this order of priority:

OutcomeTriggerResult
1Deliver stalereturn(deliver_stale) is executed invcl_fetch (seemore about stale content for details).An existing, stale object is served from the cache.

The downloaded response is discarded, regardless of its cacheability or proposed TTL. No changes are made to the cache.
2Deliver uncachedThe content is deemeduncacheable or has a total TTL1 of zero.

Fastly's cache deems a response uncacheable based on its HTTP status and other factors, following theHTTP Caching RFC. The default behavior of the readthrough cache also excludes responses that include aset-cookie header.

This behavior can be overridden usingberesp.cacheable.
The new response is served to the end user, and no record is made in the cache. Requests queued up due torequest collapsing are dequeued and forwarded individually to the backend.
3Cache and passreturn(pass) is executed invcl_fetch.The new response is served to the end user, and an emptyhit-for-pass object is saved into the cache. This object exists to allow subsequent requests to proceed directly to a backend fetch without being queued byrequest collapsing.

The hit-for-pass object is stored for the duration specified by its TTL, but subject to a minimum of 120 and a maximum of 3690 seconds.
4Cache and deliverAll other cases (return(deliver) either explicitly or implicitly).The new response is served to the end user, used to satisfy queued requests, and stored in cache for up to the duration specified by its TTL.

IMPORTANT: Objects may not be stored for the full TTL requested, as they may get evicted earlier in favor of more popular objects, especially if they are large. Objects are not automatically evicted when they reach their TTL, they simply becomestale.

If you are experiencing a slow request rate or timeouts on uncacheable resources, it may be because they are forming queues that can be solved by creating ahit-for-pass. For more details, seerequest collapsing.

Stale objects and revalidation

An object that has reached its TTL becomes stale. If an object is requested while it is stale, it may trigger a revalidation request to the backend. Learn more aboutstaleness and revalidation.

Preventing content from being cached

Since Fastly respects HTTP caching semantics in the readthrough cache, the best way to avoid caching content is to set the appropriateCache-Control header on responses at the backend.

Preventing caching at the edge and in browsers

Responding with the following header will ensure that the object will not be cached by Fastly (theprivate directive), and that it will not be cached by any other downstream cache, such as a browser (bothprivate andno-store directives):

Cache-Control:private, no-store

Cache at the edge, not in browsers

You may want the content to be cached by Fastly but not by browsers. You can do this purely in the initial HTTP response header from the backend:

Cache-Control:s-maxage=3600, max-age=0
  1. CDN services
  2. Compute services
  3. Rust
  4. JavaScript
  5. Go

In a VCL service, you can apply an override invcl_fetch:

setberesp.http.Cache-Control="private, no-store";# Don't cache in the browser
setberesp.ttl=3600s;# Cache in Fastly
setberesp.ttl-=std.atoi(beresp.http.Age);
return(deliver);

Cache in browsers, not at the edge

Fastly will not cacheprivate content, making it a good way to apply this kind of differentiated caching policy via a single header attached to the response from your origin server:

Cache-Control:private, max-age=3600
  1. CDN services
  2. Compute services
  3. Rust
  4. JavaScript
  5. Go

In a VCL service, you can also apply the same logic invcl_fetch:

setberesp.http.Cache-Control="max-age=3600";# Cache in the browser
return(pass);# Don't cache in Fastly

Overriding cache behavior on requests

Sometimes you may know what cache behavior you'd like for the response before forwarding a request to the backend.

For details, see the following sections.

IMPORTANT: As noted incache outcome above, where requests are flagged to bypass the readthrough cache or have an override TTL of 0, the response will never be cached.

Related content


  1. "Total TTL" isberesp.ttl +beresp.stale_while_revalidate +beresp.stale_if_error
  2. "Total TTL" isresp.get_ttl() +resp.get_stale_while_revalidate()

[8]ページ先頭

©2009-2025 Movatter.jp