Back to Blog

Content Delivery Network Guide: CDN Architecture, Edge Caching, and Cloudflare Workers

Understand CDN architecture and edge caching — how CDNs work, cache-control headers, cache invalidation, Cloudflare Workers for edge logic, and when CDNs don't

Viprasol Tech Team
April 25, 2026
12 min read

Content Delivery Network Guide: CDN Architecture, Edge Caching, and Cloudflare Workers

A CDN (Content Delivery Network) is a geographically distributed network of cache servers that serve your content from locations close to users. A request from Tokyo that would normally travel to your US origin server — 150–200ms round trip — instead hits a CDN edge node in Tokyo at 5–10ms.

But CDNs are commonly misunderstood: they cache more than static files, they require careful configuration to work correctly, and they can cause bugs (stale content, cache poisoning) if set up wrong.


How CDNs Work

User (Tokyo) → CDN Edge (Tokyo) → Origin Server (US East)

First request:
  User → Tokyo edge → MISS → Origin (150ms) → Cache response → User

Subsequent requests (while cached):
  User → Tokyo edge → HIT → User (5ms)

The CDN edge node caches the response. Subsequent requests for the same URL are served from cache without hitting your origin.

What gets cached:

  • Static assets: JS, CSS, images, fonts (obvious)
  • HTML pages: static site pages, pre-rendered pages
  • API responses: if you set the right headers
  • Video and audio files
  • WebAssembly modules

What doesn't get cached (by default):

  • Requests with cookies (treated as personalized)
  • POST/PUT/DELETE requests
  • Responses with Cache-Control: private or no-store
  • Responses with Set-Cookie headers

Cache-Control Headers

Your origin server controls CDN behavior via Cache-Control response headers.

// Fastify route with explicit cache directives

// Static assets — long-lived, immutable (fingerprinted filenames)
app.get('/assets/*', async (request, reply) => {
  reply.header('Cache-Control', 'public, max-age=31536000, immutable');
  // max-age=31536000: cache for 1 year
  // immutable: browser won't revalidate even on refresh
});

// API data — short-lived, serve stale while revalidating
app.get('/api/posts', async (request, reply) => {
  reply.header('Cache-Control', 'public, max-age=60, stale-while-revalidate=300');
  // max-age=60: serve fresh for 60s
  // stale-while-revalidate=300: serve stale while fetching new data (up to 5 min)
});

// User-specific data — never cache
app.get('/api/user/profile', async (request, reply) => {
  reply.header('Cache-Control', 'private, no-store');
});

// Rarely changing public data — cache for 1 hour
app.get('/api/pricing', async (request, reply) => {
  reply.header('Cache-Control', 'public, max-age=3600, s-maxage=86400');
  // max-age: browser cache TTL
  // s-maxage: CDN cache TTL (overrides max-age for shared caches)
});

Cache-Control directives reference:

DirectiveEffect
publicAny cache (CDN, browser) can store
privateBrowser only — CDN must not cache
no-storeDon't cache anywhere
no-cacheCache, but always revalidate before serving
max-age=NCache for N seconds (browser + CDN)
s-maxage=NCDN cache TTL (overrides max-age for CDNs)
stale-while-revalidate=NServe stale while fetching fresh
stale-if-error=NServe stale if origin errors
immutableDon't revalidate (use only with fingerprinted assets)

☁️ Is Your Cloud Costing Too Much?

Most teams overspend 30–40% on cloud — wrong instance types, no reserved pricing, bloated storage. We audit, right-size, and automate your infrastructure.

  • AWS, GCP, Azure certified engineers
  • Infrastructure as Code (Terraform, CDK)
  • Docker, Kubernetes, GitHub Actions CI/CD
  • Typical audit recovers $500–$3,000/month in savings

Cloudflare Configuration

Cloudflare is the most widely used CDN/edge platform. Key configuration:

Page Rules (or Ruleset) for cache behavior:

Rule: Cache static assets aggressively
URL: *yourdomain.com/assets/*
Cache Level: Cache Everything
Edge Cache TTL: 1 year

Rule: Bypass cache for API routes
URL: *yourdomain.com/api/*
Cache Level: Bypass
(unless your API explicitly sets Cache-Control: public)

Rule: Cache HTML pages
URL: *yourdomain.com/blog/*
Cache Level: Cache Everything
Edge Cache TTL: 1 hour
Browser Cache TTL: 30 minutes

Cloudflare Terraform config:

# terraform/cloudflare.tf
resource "cloudflare_ruleset" "cache_rules" {
  zone_id = var.cloudflare_zone_id
  name    = "Cache rules"
  kind    = "zone"
  phase   = "http_request_cache_settings"

  rules {
    action = "set_cache_settings"
    action_parameters {
      cache = true
      edge_ttl {
        mode    = "override_origin"
        default = 86400  # 24 hours
      }
      browser_ttl {
        mode    = "override_origin"
        default = 3600  # 1 hour
      }
    }
    expression  = "(http.request.uri.path matches \"^/blog/\")"
    description = "Cache blog pages"
    enabled     = true
  }

  rules {
    action = "set_cache_settings"
    action_parameters {
      cache = false  # Bypass CDN cache for API
    }
    expression  = "(http.request.uri.path matches \"^/api/user\")"
    description = "Bypass cache for user-specific API routes"
    enabled     = true
  }
}

Cache Invalidation

The classic engineering problem: "There are only two hard things in Computer Science: cache invalidation and naming things."

Strategies:

1. URL fingerprinting (best for assets) Include a content hash in the filename. When the file changes, the URL changes, the old URL expires naturally.

/assets/main.abc123de.js   ← hash changes with file content

Next.js, Vite, and Webpack do this automatically.

2. Versioned paths

/api/v1/pricing   ← Old version
/api/v2/pricing   ← New version serves updated data

3. Explicit purge via API

// Purge specific URLs after content update
async function purgeCloudflareCache(urls: string[]) {
  const response = await fetch(
    `https://api.cloudflare.com/client/v4/zones/${process.env.CF_ZONE_ID}/purge_cache`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.CF_API_TOKEN}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ files: urls }),
    }
  );

  if (!response.ok) {
    throw new Error(`Cache purge failed: ${await response.text()}`);
  }

  return response.json();
}

// Call after publishing a blog post
await purgeCloudflareCache([
  'https://yourdomain.com/blog/',
  'https://yourdomain.com/blog/new-post-slug/',
  'https://yourdomain.com/sitemap.xml',
]);

4. Short TTL + stale-while-revalidate For content that changes frequently, use a short TTL so staleness is bounded:

Cache-Control: public, max-age=60, stale-while-revalidate=300

The CDN serves stale content instantly while fetching fresh — users see fast responses, content updates within 5 minutes.


⚙️ DevOps Done Right — Zero Downtime, Full Automation

Ship faster without breaking things. We build CI/CD pipelines, monitoring stacks, and auto-scaling infrastructure that your team can actually maintain.

  • Staging + production environments with feature flags
  • Automated security scanning in the pipeline
  • Uptime monitoring + alerting + runbook automation
  • On-call support handover docs included

Cloudflare Workers: Edge Logic

Cloudflare Workers let you run JavaScript at the CDN edge — before requests hit your origin. Use cases: A/B testing, authentication, request modification, geolocation routing.

// workers/ab-test.ts — A/B test routing at the edge
export default {
  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);

    // Only A/B test the pricing page
    if (url.pathname !== '/pricing') {
      return fetch(request);
    }

    // Assign variant based on cookie or random
    const cookie = request.headers.get('Cookie') || '';
    const variantMatch = cookie.match(/ab_pricing=([ab])/);

    let variant: 'a' | 'b';
    if (variantMatch) {
      variant = variantMatch[1] as 'a' | 'b';
    } else {
      variant = Math.random() < 0.5 ? 'a' : 'b';
    }

    // Route to different origin paths
    const targetUrl = variant === 'b'
      ? new URL('/pricing-v2', url.origin).toString()
      : request.url;

    const response = await fetch(targetUrl, request);

    // Set variant cookie
    const newResponse = new Response(response.body, response);
    if (!variantMatch) {
      newResponse.headers.append('Set-Cookie',
        `ab_pricing=${variant}; Path=/; Max-Age=86400; SameSite=Lax`
      );
    }

    return newResponse;
  },
};
// workers/geo-redirect.ts — serve region-specific content
export default {
  async fetch(request: Request): Promise<Response> {
    const country = request.headers.get('CF-IPCountry') || 'US';
    const url = new URL(request.url);

    // Redirect EU users to GDPR-compliant endpoint
    const euCountries = ['DE', 'FR', 'NL', 'IT', 'ES', 'PL', 'SE', 'NO'];
    if (euCountries.includes(country) && !url.hostname.startsWith('eu.')) {
      return Response.redirect(
        `https://eu.${url.hostname}${url.pathname}${url.search}`,
        302
      );
    }

    return fetch(request);
  },
};

CDN Provider Comparison (2026)

ProviderFree TierPricing ModelEdge LocationsBest For
CloudflareUnlimited bandwidth$0–$200/mo fixed320+Most use cases
AWS CloudFront1TB/mo free$0.0085–0.12/GB450+AWS-native apps
FastlyNone$0.12/GB70+Enterprise, VCL control
Vercel EdgeIncludedPart of Vercel planVariesNext.js apps
Bunny CDNNone$0.005–0.06/GB120+High-volume, low cost

For most startups: Cloudflare (free tier covers most traffic, Workers included, DDoS protection included). For AWS-native deployments: CloudFront + Lambda@Edge.


When CDNs Don't Help

CDNs don't fix slow APIs, dynamic content, or small user bases:

  • Uncacheable dynamic content: If every response is unique (personalized dashboards), a CDN provides only DDoS protection, not caching benefit
  • Small user base in one region: If all users are in one city, latency reduction is minimal — focus on origin performance
  • Slow database queries: CDN caches at the HTTP layer; a 3-second database query is still 3 seconds on cache miss
  • High cache invalidation rate: If content changes every minute and TTL is 60 seconds, cache hit rate is low

Working With Viprasol

We configure CDN infrastructure as part of cloud deployments — Cloudflare setup, cache-control header strategy, Workers for edge logic, and performance audits that identify what to cache vs. optimize at the origin.

Talk to our cloud team about CDN and performance optimization.


See Also

Share this article:

About the Author

V

Viprasol Tech Team

Custom Software Development Specialists

The Viprasol Tech team specialises in algorithmic trading software, AI agent systems, and SaaS development. With 100+ projects delivered across MT4/MT5 EAs, fintech platforms, and production AI systems, the team brings deep technical experience to every engagement. Based in India, serving clients globally.

MT4/MT5 EA DevelopmentAI Agent SystemsSaaS DevelopmentAlgorithmic Trading

Need DevOps & Cloud Expertise?

Scale your infrastructure with confidence. AWS, GCP, Azure certified team.

Free consultation • No commitment • Response within 24 hours

Viprasol · Big Data & Analytics

Making sense of your data at scale?

Viprasol builds end-to-end big data analytics solutions — ETL pipelines, data warehouses on Snowflake or BigQuery, and self-service BI dashboards. One reliable source of truth for your entire organisation.