Accelerate Delivery & Offload Origin

These settings govern delivery performance and how the edge interacts with your origin and with end users. The two caching templates are where most of the value is: effective caching reduces origin load, saves bandwidth, and puts assets closer to your users.

dnsAsyncRefresh

 {
  "name": "dnsAsyncRefresh",
  "options": {
    "enabled": true,
    "timeout": "5h"
  }
}

Defines how edge servers behave when your origin's DNS A record expires. Enabled, the edge forwards the current request using the expired record while refreshing the record in the background. Disabled, the edge has to resolve DNS before forwarding, and a slow or failed resolution turns into user-perceived latency or a denial of service.

timeout is how long an expired record stays usable while the refresh happens. 5 hours is the Ion best practice, and it's an intentional override: the behavior's own default is 2 hours.

📘

timeout is only available while enabled is true. If you set enabled to false and later back to true without restating timeout, you get the behavior default of 2 hours, not Ion's 5.

For finer control over origin timeouts, add the optional readTimeout and connectTimeout behaviors to a rule.

http3

{
  "name": "http3",
  "options": {
    "enable": true
  }
}

HTTP/3 replaces TCP with the IETF QUIC protocol, which means faster connection setup and more
efficient stream handling.

Requires TLS 1.3 for client-to-edge requests.

http2

{
  "name": "http2",
  "options": {
    "enabled": ""
  }
}

HTTP/2 gives you concurrent downloads over one TCP connection, object prioritization, and header compression. It's enabled on the platform and can't be turned off, which is why the option carries an empty placeholder value rather than a boolean. Send the object as the template delivers it.

allowTransferEncoding

{
  "name": "allowTransferEncoding",
  "options": {
    "enabled": true
  }
}

Allows chunked transfer encoding, which improves performance for large content by breaking data into chunks so one large download can't block a connection.

  • Chunked transfer encoding has to be enabled on your origin too.
  • Don't set this to false if you use HTTP/2 or HTTP/3. Denying chunked encoding there results in a denial of service for clients requesting chunked content — and HTTP/3 is on by default in this same template.

sureRoute

{
  "name": "sureRoute",
  "options": {
    "enabled": true,
    "type": "PERFORMANCE",
    "testObjectUrl": "/akamai/sureroute-test-object.html",
    "toHostStatus": "INCOMING_HH",
    "raceStatTtl": "30m",
    "forceSslForward": false,
    "enableCustomKey": false,
    "srDownloadLinkTitle": ""
  }
}

SureRoute finds the fastest path between edge servers and your origin by racing candidate routes, and keeps failover paths available. It's aimed at non-cacheable content — for anything cacheable, serving from the edge beats any origin route, so the platform disables SureRoute automatically when it detects cacheable content.

OptionShips asWhy
typePERFORMANCERaces three simultaneous paths, triggered by real end-user requests for non-cacheable content, and promotes the fastest. Adapts as internet conditions change. The alternative is CUSTOM_MAP, which needs a map from Akamai.
testObjectUrl/akamai/sureroute-test-object.htmlThe object the races request. The path is seeded for you, but you must put the object on your origin.
toHostStatusINCOMING_HHRaces use the forward host header you already set for your origin, so they test the same request path real traffic takes. Use OTHER with toHost to race a different hostname.
raceStatTtl30mHow long a race result is reused before the next race. Long enough to amortize the cost of racing, short enough to track changing conditions.
forceSslForwardfalseRaces follow the request's protocol. Set true if your origin only accepts HTTPS.
enableCustomKeyfalseRace results are stored per origin hostname. With true, customStatKey sets the grouping explicitly.

Disable SureRoute if this configuration serves only cacheable content.

earlyData

{
  "name": "earlyData",
  "options": {
    "enabled": true
  }
}

Early Data (0-RTT) is a TLS 1.3 feature that lets a client resuming a session send data during the handshake, removing a round trip and reducing time to first byte. Ion enables it because the latency win applies to exactly the requests Ion exists to accelerate.

Akamai only applies Early Data to GET requests without query parameters, which limits exposure to replay attacks.

Before you leave this on, confirm:

  • Secure connection. Your certificate's deployment settings must have TLS 1.3 enabled.
  • Compatibility. Early Data is incompatible with the enforceMtlsSettings behavior. You can't
    use both.
  • Origin support. Your origin must recognize the Early-Data: 1 header and should return HTTP 425 (Too Early) for requests it can't safely process over 0-RTT.

To extend 0-RTT beyond GET requests, add the earlyDataAdvanced behavior to a rule. It isn't part of the Ion default settings.

cachingTemplate

The largest setting in the template, and the one most worth understanding before you change anything. "Origin offload" is the share of content Akamai serves instead of your origin, and this is where you control it.

{
  "name": "cachingTemplate",
  "options": {
    "cachingOption": "CACHE_FEW_OBJECTS",
    "tieredDistribution": true,
    "validateEntityTag": true,
    "removeVaryHeader": false,
    "cacheKeyQueryParams": "INCLUDE_ALL_ALPHABETIZE_ORDER",
    "cacheHttpTemporaryRedirects": false,
    "cacheHttpErrorResponse": true,
    "cacheHttpErrorTtl": "10s",
    "cacheHttpErrorPreserveStale": true,
    "prefreshCache": true,
    "prefreshCacheTtlPercentage": 90,
    "applyCssJsCaching": true,
    "cacheCssJsExtensions": ["css", "js"],
    "cacheCssJsPolicy": "MAX_AGE",
    "cacheCssJsTtl": "7d",
    "cacheCssJsForceRevalidateCache": false,
    "applyFontsCaching": true,
    "cacheFontsExtensions": ["eot", "woff", "woff2", "otf", "ttf"],
    "cacheFontsPolicy": "MAX_AGE",
    "cacheFontsTtl": "30d",
    "cacheFontsForceRevalidateCache": false,
    "applyImagesCaching": true,
    "cacheImagesExtensions": ["jpg", "jpeg", "png", "gif", "webp", "jp2", "ico", "svg", "svgz"],
    "cacheImagesPolicy": "MAX_AGE",
    "cacheImagesTtl": "30d",
    "cacheImagesForceRevalidateCache": false,
    "applyFilesCaching": true,
    "cacheFilesExtensions": ["pdf", "doc", "docx", "odt"],
    "cacheFilesPolicy": "MAX_AGE",
    "cacheFilesTtl": "7d",
    "cacheFilesForceRevalidateCache": false,
    "applyHtmlCaching": true,
    "cacheHtmlExtensions": ["html", "htm", "php", "jsp", "aspx", "EMPTY_STRING"],
    "cacheHtmlPolicy": "NO_STORE",
    "applyOthersCaching": true,
    "cacheOthersExtensions": ["aif", "aiff", "au", "avi", "bin", "..."],
    "cacheOthersPolicy": "MAX_AGE",
    "cacheOthersTtl": "7d",
    "cacheOthersForceRevalidateCache": false
  }
}

cacheOthersExtensions is abbreviated here.

Caching policy

cachingOption ships as CACHE_FEW_OBJECTS — cache specific objects, selected by file extension. This is an override of the behavior's CACHE_ALL default, and it's the decision that shapes the rest of the setting: it's why all six apply*Caching switches are on and why each content type gets its own policy, TTL, and extension list.

ValueEffect
CACHE_FEW_OBJECTSShips as this. Per-content-type caching by file extension. Makes the apply*Caching options available.
CACHE_ALLOne policy for everything. Makes cacheTtl and cacheForceRevalidate available instead.
CACHE_NONENo edge caching. Hides tieredDistribution, cacheKeyQueryParams, prefreshing, and the per-type options.
❗️

Switching cachingOption changes which options are valid

The per-type options (applyImagesCaching, cacheImagesTtl, and the rest) are only available under CACHE_FEW_OBJECTS. cacheTtl and cacheForceRevalidate are only available under CACHE_ALL. tieredDistribution, validateEntityTag, removeVaryHeader, cacheKeyQueryParams, cacheHttpErrorResponse, and the prefresh options need CACHE_ALL or CACHE_FEW_OBJECTS, so a switch to CACHE_NONE invalidates all of them. Rebuild the options object when you change this value.

Content-specific caching

The TTLs follow how often each content type actually changes:

Content typeShips asWhy
CSS and JavaScriptMAX_AGE, 7dVersioned or fingerprinted in most build pipelines, so a week of caching is safe.
FontsMAX_AGE, 30dEffectively static once published.
ImagesMAX_AGE, 30dStatic once published, and the biggest offload win by bytes.
Files (pdf, doc, docx, odt)MAX_AGE, 7dDocuments change more often than images and are more likely to be replaced in place.
HTMLNO_STOREHTML changes frequently and is the most likely to carry per-user content, so edge servers always check the origin.
OtherMAX_AGE, 7dA broad extension list of media, archives, and binaries, at a conservative TTL.

Each type has three companion options: apply<Type>Caching turns the block on, cache<Type>Policy is MAX_AGE or NO_STORE, and cache<Type>Ttl sets the duration. A MAX_AGE policy also makes cache<Type>ForceRevalidate available.

❗️

Never cache files containing personally identifiable information (PII). The Files block caches
pdf, doc, docx, and odt for 7 days by default — if any of those are per-user documents on your origin, narrow the extension list or override the path in a rule.

📘

EMPTY_STRING in the HTML extension list

cacheHtmlExtensions includes the literal "EMPTY_STRING", which matches URLs with no file extension. That's what makes the HTML NO_STORE policy apply to paths like / and /about rather than only to /index.html. Keep it unless you deliberately want extensionless URLs falling through to another block.

Cache key, validation, and offload

OptionShips asWhy
cacheKeyQueryParamsINCLUDE_ALL_ALPHABETIZE_ORDERAll parameters stay in the cache key, but reordered alphabetically, so ?a=1&b=2 and ?b=2&a=1 are one object instead of two. A straight cache-hit improvement with no change to what users receive. The other values are INCLUDE_ALL_PRESERVE_ORDER, IGNORE_ALL, INCLUDE, and IGNORE; the last two take a parameter list.
tieredDistributiontrueAdds a parent caching tier between edge servers and your origin. An edge miss checks the parent before going to your origin. Note that it creates midgress traffic (edge-to-parent), which appears as its own category in traffic reports.
validateEntityTagtrueCompares a request's If-None-Match against the cached object's ETag and answers 304 Not Modified when they match, so a revalidation costs headers instead of a body. This is in addition to Last-Modified / If-Modified-Since validation.
removeVaryHeaderfalseAkamai doesn't cache responses carrying a Vary header, even when the content is otherwise cacheable. Removing the header raises hit rates but discards the origin's statement that the response varies — so it ships off, as a deliberate opt-in.
prefreshCachetrueRefreshes an object asynchronously just before it expires, so the next user doesn't wait on your origin.
prefreshCacheTtlPercentage90Refresh starts at 90% of the TTL — for a 10-minute TTL, at the 9-minute mark — leaving your origin time to respond before the object actually expires. Prefresh only triggers if a request arrives inside that window, so set it low enough to cover your origin's typical response time.
cacheHttpTemporaryRedirectsfalse302 and 307 responses are temporary by definition, so they aren't cached. Set true to cache them the way 301 and 308 are cached.
cacheHttpErrorResponsetrueCaches error responses (204, 305, 404, 405, 414, 501–504) so repeated requests for missing content don't reach your origin — protection that matters most during an outage.
cacheHttpErrorTtl10sLong enough to absorb a burst, short enough that a fixed error clears almost immediately. 0 sends every request to your origin.
cacheHttpErrorPreserveStaletrueWhile your origin is struggling, serve a stale cached object rather than a fresh error.
📘

Error responses larger than 64 KB — often custom 404 pages — aren't cached by default. Contact your Akamai representative to raise the limit.

downstreamCacheTemplate

Where cachingTemplate governs the edge, this governs caching downstream of the edge: browsers, mobile apps, and corporate proxies.

{
  "name": "downstreamCacheTemplate",
  "options": {
    "cacheOption": "ALLOW",
    "cacheLifetime": "LESSER",
    "sendHeaders": "CACHE_CONTROL",
    "sendPrivate": false,
    "bustUncacheable": true,
    "applyHtmlCaching": false
  }
}
OptionShips asWhy
cacheOptionALLOWStandard downstream storage is permitted. Alternatives: MUST_REVALIDATE (store but revalidate before every use), BUST (never store), TUNNEL_ORIGIN (pass your origin's headers through unchanged), NONE (send no cacheability headers and let browser defaults apply).
cacheLifetimeLESSERClients are told to cache for whichever is shorter: the time left in the edge cache or the value from your origin headers. The conservative choice — a client never holds content longer than the edge would.
sendHeadersCACHE_CONTROLCache-Control alone is unambiguous and is what every current client honors. Expires is a legacy duplicate that can conflict. Other values: CACHE_CONTROL_AND_EXPIRES, EXPIRES, PASS_ORIGIN.
sendPrivatefalseAdding private restricts caching to the end user's own device, which also prevents shared-proxy caching. Off by default; turn it on for per-user responses.
bustUncacheabletrueFor content the edge won't cache, actively prevent downstream caching by sending Expires: [current time], Cache-Control: max-age=0, Cache-Control: no-store, Cache-Control: no-cache, and Pragma: no-cache. This is what keeps uncacheable responses — the Ion template's NO_STORE HTML among them — out of browser and proxy caches.
applyHtmlCachingfalseNo separate downstream policy for HTML, so HTML follows the settings above.

cacheLifetime is only available with cacheOption: ALLOW, and ttl only with cacheLifetime: FROM_VALUE. Setting ttl to 0 forces revalidation and sends all cache-busting headers downstream, whatever sendHeaders says.

Turning on applyHtmlCaching opens a parallel set of options for HTML alone — cacheHtmlOption, cacheHtmlExtensions, cacheHtmlLifetime, cacheHtmlTtl, cacheHtmlSendHeaders, cacheHtmlSendPrivate, cacheHtmlBustUncacheable.