Learn about caching

One of the core benefits of ‚ÄčAkamai‚Äč CDN is the ability to retrieve content from origin servers and cache it in ‚ÄčAkamai‚Äč servers at the edge of the Internet, near end-users. This feature improves performance by reducing the load on the origin server and reducing the time required to serve content to end-users.

Property Manager automatically assigns a caching setting to your content. By default, edge servers cache content for a theoretically infinite time. Objects are removed from cache on a least recently used (LRU) basis. If a server is retrieving new content for an already full cache, one or more object(s) may be removed from cache if not requested in as little as as a single day. However, if the server is under a light load, an object may remain in cache for as long as the TTL dictates. If it's critical that an object is truly inaccessible, for whatever reason, you can purge it within seconds using the Purge Cache application.

To change the default settings, you can modify the Time-to-Live (TTL) value through behaviors, the main one being Caching, or set certain response headers sent by your origin.

What is TTL?

Time-to-live (TTL) is the amount of time an edge server will hold an object in its cache, without revalidating whether it has been modified with the origin server. When end-users send a request, edge servers compare the timestamp of the object in cache with the current time. If the resulting age is greater than the TTL specified in the configuration or metadata such as response headers, edge servers must refresh the object before serving it. To check with the origin, edge servers use a conditional HTTP If-Modified-Since (IMS) GET request. If the object has changed, the origin server sends the new version; otherwise, the origin sends a 304 Not Modified response.

Refreshing occurs only if the object is requested by a client. Also, the IMS GET request is sent only if Last-Modified-Time (LMT) header is present. If this header isn't present, edge servers send the unconditional GET request.

How to set TTL?

Your property configuration is the primary method for setting options across groupings of objects, and it's the main method for setting TTL. In behaviors and matches, you set the max-age value that defines the maximum amount of time that fetched responses are allowed to be used again. Usually, you set it to the maximum acceptable value, based on which the remaining TTL is calculated. See the Caching behavior for more information. By applying matches to your rules, you can specify a variety of max-age settings that best suit your needs, for example match on file directories, file extensions, and other groupings.

If necessary, you can override the configuration settings on selected objects with Edge Side Incldes (ESI) attributes, ‚ÄčAkamai‚Äč Resource Locators (ARLs), and specific headers coming from the origin server, such as Edge-Control, Cache-Control, and Expires.

ESI tag attributes

This may be of interest to ESI developers. When you use an esi:include statement to request a fragment for inclusion in an ESI template page, you can use the ttl or no-store attributes to control the caching properties for the requested object.

ARLs

If you use the traditional Akamaization, you can assign a TTL in the object‚Äôs ARL. The ARL relates to a specific request and it takes precedence over both the configuration file and settings in the Edge-Control header. Contact your ‚ÄčAkamai‚Äč representative for more information.

Edge-Control header

The Edge-Control header is an ‚ÄčAkamai‚Äč specific header. Using the value cache-maxage, you can override other cache directives. The header and value are sent from the origin server's response. This is the fastest way to make a content cacheable or non-cacheable without making any changes to the configuration. The header is suitable either for temporary or frequent TTL changes.

The value used in cache-maxage is an integer, followed by a unit specifier: s (seconds), m(minutes), h (hours), d (days). For example:

Edge-control: cache-maxage=30m

Cache-Control and Expires headers

By default, edge servers do not honor these two response headers sent from the origin server. You can change that setting for specific objects. Enabling each header separately, or both. Once enabled, the edge network honors the following, and only the following, Cache Control header directives:

  • max-age
  • no-store
  • no-cache (behaves like setting a zero second max-age)
  • pre-check (serves as a max-age setting if there is no max-age)
  • post-check (serves as an ‚ÄčAkamai‚Äč refresh setting)

ūüöß

Potential conflicts

If there are conflicts between the Cache Control and Expires headers when both are honored, the Cache-Control value prevails. However, you can't override a no-store metadata setting with a Cache-Control or Expires header. To override a no-store, turn the no-store off. Using response headers, you can turn the no-store off with Edge-Control: !no-store.

Other considerations:

  • You can use the behaviors to set the Cache-Control headers, and if your property configuration is set to honor Cache-Control, you can also use Microsoft extensions for Internet Explorer‚ÄĒa post-check and a pre-check directive in the header.

  • If you set the configuration to honor Cache-Control headers, edge servers use that information for the lifetime of the object if these conditions are fulfilled: you set edge servers to accept max-age, no-store, and no-cache directives, and they receive the header in the response from the origin server.

  • If you set the configuration to honor Expires, edge servers use the implied max-age as the lifetime for the object if these conditions are fulfilled: edge servers receive this header in the response from the origin server, and the expiration is in the future.

  • When you enable honoring and an edge server receives an Expires header from the origin, it may happen that the origin clock isn't synchronized with the ‚ÄčAkamai‚Äč server‚Äôs clock. For this reason, the edge server uses an implied max-age to calculate the remaining TTL, and it's the time the edge server uses to set its own TTL. Arithmetically, the implied max-age may be shown as:

    IM (implied max-age) = OE (Origin Expires) - OD (Origin Date)

    For example, if the origin's Expires is set for 5:00 p.m. today, and the origin time is currently 10:00 a.m., the implied max-age is 7 hours. By using the origin date, the edge server calculates the intended TTL. If it used its own date and the origin's Expires, and if there was a discrepancy between the edge server’s clock and the origin’s clock, the calculated TTL might have been more or less than you intended.

ūüďė

Past date

If the received Expires is in the past, edge servers use their own current date stamp now instead of the implied max-age.

TTL best practices

The choice of an appropriate TTL is based on the time-sensitivity and the nature of the objects. In general, you will want to select the longest possible TTL that would not result in the end-user receiving stale content. The longer the TTL associated with an object the more benefit is received from offloading content. In addition, longer TTL makes means reduced latency, since the requested object is served form an edge server, physically closer to that user.

Prefresh

If the object is popular, even a short TTL can result in reducing the waiting time for the end-user, because the ‚ÄčAkamai‚Äč server prefreshes objects asynchronously with client requests if a request comes during the specified time percentage of TTL. Prefresh is turned on by default and set to 90%. This means that after 90% of the TTL has expired, a request for the object triggers an asynchronous IMS request to the origin while the cached object is served to the client.

For example, an object with a TTL of ten minutes is requested 50 seconds before it expires. The ‚ÄčAkamai‚Äč server first serves the object to the client and then sends an If-Modified-Since request to the origin server to revalidate the object. This asynchronous update avoids a delay in serving the object at the next request.

To change the default setting, add the Cache Prefresh/Refresh behavior to your property configuration.

Time intervals

If you use behaviors to manage your TTL, you have an option to set TTLs based on a particular starting time, for a particular time period, to be repeated some number of times, until a particular expiration time. The expiration in this case concerns the particular TTL setting, not with the object expiring from cache. You can set short TTLs for objects when they are likely to change frequently and longer TTLs when they are more likely not to change as often.

Time sensitivity

While choosing time-to-live settings, consider this question: How long do I want ‚ÄčAkamai‚Äč to serve this cached version after I've already changed the content on my site? The answer to this question may be the appropriate TTL for your content.

  • Extreme time sensitivity. If an object is so time sensitive that it must be revalidated each time it's served, like a breaking news story, then you should either not serve the object from cache at all, or set TTL=0 (zero TTL) so that the object is cached but its freshness is revalidated with each request. The choice of whether to prevent caching (no-store) or assign zero-TTL may depend primarily on the size of your object.

  • Moderate time sensitivity. If you update the site once a day in the late evening when the traffic is low, you might not mind serving stale content for some time. You can set TTL for most objects to an hour or more. You might even assign longer TTLs and use Purge Cache in the publication process to purge old content after each new publication. However, mind that a change in content doesn't warrant purging the old content from cache. Time-sensitivity is the primary issue. For example, if you make superficial changes to an image and there is no urgency for the user to see the updated version, you can let the changes take effect gradually as edge servers revalidate old objects in cache with the origin server.

  • No time sensitivity. If content isn't time sensitive at all‚ÄĒfor example, an archival magazine article‚ÄĒyou can give it a very long TTL. It's probably most beneficial if the origin server isn't bothered with If-Modified-Since requests to confirm the freshness of the object. You can keep the object fresh by either changing the reference in the HTML when the content changes, or using Purge Cache to purge the old content after it has been changed.

Downstream caching

Downstream refers to the caching instructions edge servers apply to the content they serve to the clients, such as browsers, mobile devices, or client proxies.

ūüďė

Downstream no-store and bypass-cache instructions override other downstream TTL instructions. If the object can’t be cached, the TTL is irrelevant.

The default behavior

By default, ‚ÄčAkamai‚Äč sets cacheability at the browser to no longer than the remaining lifetime for the content stored in the edge server cache. If the cacheability headers sent by the origin server suggest a shorter time, the shorter time is used.

When delivering content to clients, ‚ÄčAkamai‚Äč servers by default send the lesser of the Cache-Control: max-age and/or Expires values received from the origin server, and the remaining lifetime of the object in the edge server cache. This means that the downstream max-age is always equal to or lower than the edge max-age.

Exceptions

Edge servers only update the values in the Cache-Control and Expires headers. They don't add these headers if the origin server didn't send them. However, there are certain exceptions to the default behavior:

  • If you use no-store or bypass-cache settings in your property configuration to indicate that an object shouldn't be cached, edge servers send cache-busting headers downstream. Any max-age received from the origin server is ignored.

  • The Edge-control: cache-maxage header is treated as an HTTP Cache-Control header for downstream purposes.

  • You can set the edge server configuration to compute the downstream caching itself.

  • If you use centralized authorization, edge servers send cache-busting headers downstream to prevent proxies from caching the responses and serving them to unauthorized clients. While it isn't recommended, you may configure ‚ÄčAkamai‚Äč to not cache-bust for authorized content.

  • If you use ESI, the downstream cacheability is calculated to be the lowest value of all the fragments that create the output page served to the client.

Custom TTL downstream settings

If you want to set the downstream TTL directly, without relying on the default behavior, you can either use:

  • Response headers from the origin, including the Edge-Control header.

  • The Downstream Cacheability behavior.

  • ESI configuration file or ESI language controls. With ESI Downstream Time-to-Live, you can only set a specific value in the response. There are no controls for selecting the headers to send or the method by which the value of those headers should be calculated.

Cache prevention

If you specify no caching for your object in the property configuration, or if edge servers receive the Edge-control: no-store header in the response from the origin server, the object isn't cached, and all downstream caching is also prevented.

To bust downstream caches, edge servers send these HTTP headers in response to the client:

  • Expires: <current_time>
  • Cache-Control: max-age=0
  • Cache-Control: no-store
  • Pragma: no-cache

Edge servers don't include Cache-Control: no-store in the headers sent downstream if the origin responds with Edge-control: bypass-cache instead of no-store.

With the Cache-Control header enabled in your settings, the cache-busting behavior also applies if edge servers receive Cache-Control: no-cache or Cache-Control: no-store headers in a response from the origin server. It's also true if the origin response included the Expires header in the past, but no Cache-Control: max- age.

Note that the ARL-based instructions take precedence over the Cache-Control and Expires headers. However, the cache-busting behavior does apply to objects that take their coherence settings from the property configuration.

If you want to cache in edge servers but prevent downstream caching only, you can:

  • In the Downstream Cacheability behavior, with Caching Option set to Allow caching and Cache Lifetime set to Fixed value, set the maxage value to -1.

  • Use the ESI function $add_cachebusting_header(), or set the ESI downstream TTL configuration attribute to -1.

  • Set the response header to Edge-control: cache-maxage=1h, downstream-ttl=-1. This instructs edge servers to cache the object for one hour while at the same time passing downstream cache-busting headers on each request.

TTL alternatives

In some cases, setting a TTL duration may not suit your needs. Imagine you need fresh content served the moment you publish it, for example, a market quote that needs to reflect the changes in real-time. Or, you might need to perform authentication for each request, and consequently have requests passed through to the origin. There are a few alternatives to TTL that you can apply to your objects.

Object ID coherence

A unique ID is assigned and embedded in the ARL for each object you onboard to the ‚ÄčAkamai‚Äč platform. As a consequence, every time an object changes, the ARL changes as well, even if the URI remains the same. Reach out to your ‚ÄčAkamai‚Äč representative to have the object ID coherence set as a TTL alternative.

Zero TTL

Setting a TTL to zero lets edge servers cache your object, but requires that they revalidate the object with an If-Modified-Since (IMS) request to the origin each time the object is requested. This option may be appropriate for large, time sensitive objects. If the object is large, the advantage of serving it from the edge of the Internet may outweigh the cost of revalidating the object for every client request.

You may also find zero TTL useful if you need real-time logging of end-user activity, which is a viable alternative to using no-store to ensure real-time logging. Yet, to guarantee fresh content and minimal latency, you should specify a reasonable TTL for the object and set the prefresh option to 0%. This way, edge servers contact the origin server on every request only after they serve the client to prevent increased latency caused by real-time logging.

ūüöß

If the content changes for every request, use no-store instead.

No-store

Use no-store if you don't want ‚ÄčAkamai‚Äč to cache the object. As a general rule, if the object is likely to change more often than it is requested‚ÄĒfor example, if it's different with every request‚ÄĒit's best to simply prohibit caching. No-store still achieves the benefit of the persistent TCP connections and route optimization between ‚ÄčAkamai‚Äč servers and the origin server.

If you need to pass requests and responses transparently, no-store is sometimes the only solution. You can specify no-store using the the Cache-Control: no-store or Edge-control: no-store directives. You can also use the Edge Control header to disable the no-store instruction by entering an exclamation mark before the attribute, for example Edge-control: !no-store.

For dynamically generated content, it may be essential to use no-store. However, ‚ÄčAkamai‚Äč also provides ESI (Edge Side Includes) that make it possible to serve dynamic content at the edge, near the end-user.

Bypass-cache

Bypass-cache is similar to no-store, except that it causes the request and origin response to be passed without removing the underlying object from the cache if it's already there. You can find bypass-cache useful if the object being returned is an alternate for the content that is usually delivered. You can specify bypass-cache using the the Edge-control: bypass-cache directive. With the Edge-Control header, you can also disable the bypass-cache instruction by entering an exclamation mark before the attribute, for example Edge-control: !bypass-cache.

TTL and Purge Cache

To optimize your delivery and have greater control over your content on ‚ÄčAkamai‚Äč servers, you can couple the caching settings with the use of Purge Cache. Though you should always use TTL as the primary content management solution, in some cases where content is time sensitive but changes are infrequent, you may want to set long TTLs to reduce the If-Modified-Since requests and purge the old content after it has been changed. You also may want to use Purge Cache if an object has changed and you need tight coherence‚ÄĒthat is, you can‚Äôt afford to serve the stale object for some period of time. For more information, see the Purge Cache documentation.


Did this page help you?