App Version:

Azure Front Door
CDN Cache & Purge Demo

A static-asset-rich Node.js app for end-to-end testing of caching rules, TTLs, and cache purging via Azure Front Door.

CDN architecture diagram

Live vs. Cached Response Comparison

Both panels call API endpoints on the origin. The live panel uses Cache-Control: no-store; the cached panel uses s-maxage=60. Watch the timestamps — a frozen timestamp in the cached panel confirms CDN is serving from cache.

no-store

Live Origin Response

s-maxage=60

Cacheable Response (60 s TTL)

Static Assets (86 400 s / 1 day cache)

These images are served with Cache-Control: public, s-maxage=86400. After a purge the CDN must re-fetch them from the origin. Swap an image on the server, purge the CDN path, then reload — the new image appears immediately.

Banner graphic
/images/banner.svg 86 400 s
Feature card 1
/images/card1.svg 86 400 s
Feature card 2
/images/card2.svg 86 400 s

Key CDN Response Headers

Open DevTools → Network tab and inspect these headers on any request routed through Azure Front Door.

Header Example Value Meaning
X-Cache HIT / MISS Whether the CDN served from cache or fetched from origin
X-Azure-Ref 0a1B2c… Unique Azure Front Door request reference (use for diagnostics)
Via 1.1 Azure Confirms request passed through Front Door
Age 42 Seconds the object has been in CDN cache
Cache-Control public, s-maxage=3600 Directives that Front Door honours when deciding to cache
X-App-Version 1.0.0 Custom header set by this origin — change to confirm purge worked

How It Works

Architecture, TTL configuration, the end-to-end testing workflow, and tips.

Architecture

Architecture diagram

The demo consists of a single Node.js + Express origin serving static files from /public and four JSON API endpoints. Azure Front Door sits in front and applies caching rules based on the Cache-Control headers the origin emits.

Cache TTL Configuration

Set in server.mjs via the CACHE_TTL constant.

Resource typePath patternCache-Control sentPurpose
HTML pages *.html s-maxage=300 (5 min) Short TTL so page edits propagate quickly
CSS / JS *.css, *.js s-maxage=3600 (1 hr) Medium TTL — good target for purge-on-deploy test
Images *.svg, *.png, … s-maxage=86400 (1 day) Long TTL — purge is the only fast invalidation path
JSON data /data/*.json s-maxage=60 (1 min) Short-lived data file
Live API /api/info, /api/headers no-store Always fetched from origin — baseline for comparison
Cached API /api/cached s-maxage=60 Demonstrates timestamp freeze when CDN caches JSON

End-to-End Testing Workflow

1

Verify Caching is Active

Open the Cache Test page and click Poll Cached Endpoint. After the first request (MISS) click again — the timestamp should freeze, confirming a CDN HIT. Check X-Cache: HIT in DevTools.

2

Change App Version (Simulate a Deploy)

Bump the version in package.json to 2.0.0 and restart the server. The origin now returns X-App-Version: 2.0.0, but CDN may still serve the old cached copy with 1.0.0 until TTL expires or a purge is issued.

3

Observe Stale Content

Reload static pages through the Front Door URL. Notice the old version badge is still shown — the CDN is serving the stale cached HTML/JS/CSS. Compare the X-App-Version header value to what the origin returns via /api/version (which is no-store and also reports the current process start time).

4

Purge the CDN

In the Azure Portal → Front Door → Purge cache, enter the paths to purge (e.g. /* for all, or specific paths like /index.html, /js/app.js, /images/banner.svg). You can also use the Azure CLI:

az afd endpoint purge \
  --resource-group <rg> \
  --profile-name <profile> \
  --endpoint-name <endpoint> \
  --domains <your-frontdoor-host> \
  --content-paths "/*"
5

Verify Purge Succeeded

Reload pages through Front Door. The new version badge (2.0.0) should appear, the images should update, and X-Cache should show MISS on the first request post-purge before becoming HIT again on subsequent requests.

Quick Tips

  • Use Incognito / Private mode to avoid browser cache interference.
  • Use DevTools → Network → Disable cache to always see CDN-level caching rather than browser caching.
  • The Age response header tells you how long (in seconds) an object has been sitting in the CDN cache.
  • Azure Front Door respects s-maxage over max-age when both are present.
  • Front Door will NOT cache responses that include Set-Cookie, Authorization, or no-store.
  • Use /api/headers to inspect which Azure headers Front Door is injecting into origin requests.