Skip to main content
CDN

Cache responses at the edge

How Easel CDN decides what to cache and for how long.

Easel CDN caches eligible GET and HEAD responses close to your visitors. You control CDN lifetime with cache headers on the response. Frameworks that emit standard Cache-Control directives work without extra configuration.

When to use CDN cache

CDN cache is a good fit when you want complete HTTP responses at the edge:

  • Static pages that are the same for all visitors
  • API responses that do not change often
  • Static assets such as images, fonts, and JavaScript bundles
  • Server-rendered pages with predictable lifetimes

Prefer Runtime Cache for data inside a function, and revalidation when you need to expire tagged content before TTL ends.

How to cache responses

Set cache headers on the function response:

app/api/products/route.ts
export async function GET() {
  const products = await loadProducts();
  return Response.json(products, {
    headers: {
      "Cache-Control": "public, max-age=0, must-revalidate",
      "CDN-Cache-Control": "public, s-maxage=60",
      "Vercel-CDN-Cache-Control": "public, s-maxage=3600",
    },
  });
}

Browsers revalidate every time (max-age=0). Shared CDNs may keep the response for 60 seconds. Easel CDN keeps it for one hour via Vercel-CDN-Cache-Control.

Header priority

When more than one cache header is present, Easel chooses time to live (TTL) in this order:

  1. Vercel-CDN-Cache-Control
  2. CDN-Cache-Control
  3. Cache-Control

Use CDN-Cache-Control or Vercel-CDN-Cache-Control when you want a longer edge TTL than the browser TTL.

When a response is cacheable

A response is eligible for the CDN cache when all of the following are true:

  • The method is GET or HEAD
  • The status is one of 200, 301, 302, 307, 308, or 404
  • The response does not include Set-Cookie
  • The request does not include Authorization or Range
  • The chosen cache header allows caching: it must include s-maxage or max-age greater than 0, and must not include private, no-store, or no-cache

s-maxage wins over max-age for the CDN. You can also set stale-while-revalidate to allow serving a slightly stale response while Easel refreshes the cache in the background.

Default when Cache-Control is missing

If the response has no usable CDN or Cache-Control directive, Easel does not store it in the CDN cache. For the browser, Easel applies:

Cache-Control: public, max-age=0, must-revalidate

Dynamic pages that omit Cache-Control therefore stay uncached at the edge by default.

Cache status header

Every response includes X-Easel-Cache so you can see what the CDN did:

ValueMeaning
HITServed from the CDN cache
MISSNot in cache; fetched from your deployment and stored when eligible
BYPASSNot eligible for caching
STALEServed while a background refresh is in progress
ERRORCache lookup failed; the request continued to your deployment

Keep private responses out of the CDN

Cache-Control: private, no-store

On-demand revalidation

Header TTLs alone are not enough when content changes before they expire. Tag responses and expire them from Next.js, Runtime Cache, or plain handlers. See Invalidate and revalidate cached content.