SSourav Saha
HomeExperienceSoftware DesignSystem DesignLearningBooksToolsContact
SSourav Saha

Building scalable backend systems, distributed infrastructure, and cloud-native applications.

Navigation

  • Home
  • Experience
  • Software Design
  • System Design
  • Learning

More

  • Books
  • Tools
  • Contact

Connect

  • LinkedIn
  • Email

© 2026 Sourav Saha. All rights reserved.

Built with using Next.js

System DesignContent Delivery Network (CDN)
System Designbeginner

Content Delivery Network (CDN)

How to serve static assets globally with millisecond latency. Understand CDN Edge vs Origin, Push vs Pull architectures, Anycast routing, and how to build a basic origin-pull CDN node.

January 11, 202412 min read
cdncachingnetworkingstatic-assetsbuilding-blocktier-1

Metadata

FieldValue
Slugcdn
DifficultyBeginner
Estimated Reading Time10 min
Estimated Coding Time15 min
Tier1 — Core Backend Components
Implementation LanguagePython
SEO DescriptionLearn how Content Delivery Networks (CDNs) work in system design. Understand Push vs Pull CDN strategies, Edge servers vs Origin servers, and Anycast routing.

1. Overview

What problem does it solve?

Data cannot travel faster than the speed of light. If your server is in New York, and a user is in Tokyo, a simple HTTP request takes at least 200 milliseconds just in physical transit time. If that user is downloading a 5MB image or a large JavaScript bundle, the latency is highly noticeable.

A Content Delivery Network (CDN) solves the physics problem of distance. It is a globally distributed network of servers (called Edge Servers) that cache static content (images, videos, CSS, JS) as close to the end-user as physically possible.

What breaks without it?

  • High Latency: Users far from your datacenter experience slow load times, leading to high bounce rates.
  • Bandwidth Costs: Serving terabytes of images from your primary application server (AWS EC2) is incredibly expensive compared to CDN bandwidth.
  • Server Overload: Your application servers spend all their CPU and network capacity serving static files instead of executing business logic.

2. Motivation

Why did CDNs emerge?

In the late 1990s, the internet started filling up with images and multimedia, leading to the "World Wide Wait." Akamai (the first major CDN) was born out of an MIT research project to solve this by moving the content closer to the users, effectively bypassing the congested core of the internet.

Origin vs Edge

  • Origin Server: Your primary database and application server (e.g., an EC2 instance in Virginia or an S3 bucket). The source of truth.
  • Edge Server: One of thousands of CDN servers scattered across the globe (e.g., a server rack in a Tokyo telecom building). It caches copies of the Origin's data.

3. Real-World Usage

SystemToolUse Case
NetflixOpen ConnectNetflix built their own custom CDN hardware and installed it directly inside local ISPs to stream video without buffering.
E-CommerceCloudflare / FastlyCaching product images, CSS, and JS to ensure sub-second page loads globally.
Live SportsAkamaiStreaming live video feeds to millions of concurrent viewers.
Software UpdatesAWS CloudFrontDistributing iOS updates or game patches (preventing Apple/Sony's origin servers from melting).

4. Prerequisites

ConceptBlock
DNS Resolution004 DNS & Service Discovery
Caching010 Caching Strategies

5. Visual Explanation

The Pull CDN Flow

sequenceDiagram
    participant U as User (Tokyo)
    participant Edge as CDN Edge (Tokyo)
    participant Origin as Origin Server (New York)

    Note over U,Edge: Request 1 (Cache Miss)
    U->>Edge: GET /logo.png
    Edge->>Origin: Cache Miss! Fetch /logo.png
    Origin-->>Edge: 200 OK (logo.png)
    Note over Edge: Saves to local cache
    Edge-->>U: 200 OK (logo.png) (Latency: 250ms)

    Note over U,Edge: Request 2 (Cache Hit)
    U->>Edge: GET /logo.png
    Edge-->>U: 200 OK (logo.png) (Latency: 15ms)

Anycast Routing (How the user finds the Edge)

If cdn.example.com resolves to IP 1.1.1.1, how does a user in Tokyo hit the Tokyo edge server, while a user in New York hits the New York edge server?

Anycast DNS: The same IP address (1.1.1.1) is assigned to multiple servers globally. The core internet routers (BGP) automatically route the user's TCP packets to the server physically closest to them.


6. Internal Working

6.1 Push vs Pull CDN

FeaturePull CDN (Most Common)Push CDN
How it worksEdge pulls from Origin only when a user requests it.You explicitly upload files to the CDN before users request them.
Best ForHigh traffic, rapidly changing sites, massive libraries.Small sites, predictable static assets, large video files.
ProsZero maintenance. Add a new file to Origin, CDN handles the rest.Edge always has a 100% Cache Hit rate.
ConsThe first user to request a file gets a slow "Cache Miss" penalty.Requires extra upload steps in your CI/CD pipeline.

6.2 Cache Invalidations

When you update a CSS file on the Origin, the CDN doesn't know. It will keep serving the old CSS until its TTL (Time-To-Live) expires. How to fix this?

  1. Cache Purge API: Call the CDN's API (DELETE /cache/style.css) to force it to delete the file globally. (Slow and expensive).
  2. File Versioning / Cache Busting (Industry Standard): Never update files. Always create new ones. E.g., change style.css to style.v2.css or style.a8f9c.css. The CDN treats it as a brand-new file, guaranteeing users get the latest version immediately.

7. Implementation

Why Python? We will write a simple "Edge Node" script that demonstrates the Pull CDN behavior. It will accept requests, check its local disk cache, and if missing, fetch it from a mock Origin server.

"""
012 - Pull CDN Edge Node Implementation
A simplified edge server that caches responses from an Origin server.
Run: `python cdn_edge.py`
"""
import os
import time
import requests
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse

# ── Configuration ──

# The "Origin" we are protecting (e.g., an S3 bucket or main app server)
ORIGIN_URL = "https://httpbin.org"

# Local directory to act as our CDN cache
CACHE_DIR = "/tmp/cdn_cache"

# How long to keep files in the CDN cache (seconds)
TTL = 60 

os.makedirs(CACHE_DIR, exist_ok=True)


# ── CDN Edge Server ──

class CDNEdgeHandler(BaseHTTPRequestHandler):
    
    def do_GET(self):
        parsed_path = urlparse(self.path)
        path = parsed_path.path
        
        # We use the path as the cache key. (In prod, replace slashes to avoid directory traversal)
        cache_key = path.replace("/", "_")
        if not cache_key:
            cache_key = "index"
            
        cache_file = os.path.join(CACHE_DIR, cache_key)
        
        # 1. Check if we have a valid cached copy
        if os.path.exists(cache_file):
            file_age = time.time() - os.path.getmtime(cache_file)
            if file_age < TTL:
                # ── CACHE HIT ──
                print(f"[CACHE HIT] Serving {path} from Edge (Age: {int(file_age)}s)")
                self.send_response(200)
                self.send_header("X-Cache", "HIT")
                self.end_headers()
                
                with open(cache_file, "rb") as f:
                    self.wfile.write(f.read())
                return
            else:
                print(f"[CACHE EXPIRED] {path} is older than {TTL}s.")
        
        # 2. Cache Miss or Expired -> Fetch from Origin
        print(f"[CACHE MISS] Fetching {path} from Origin ({ORIGIN_URL})...")
        origin_target = f"{ORIGIN_URL}{path}"
        
        try:
            # We add a timeout so the edge doesn't hang forever if origin is down
            resp = requests.get(origin_target, timeout=5)
            
            if resp.status_code == 200:
                # 3. Save to local cache for the next user
                with open(cache_file, "wb") as f:
                    f.write(resp.content)
                
                # 4. Serve to user
                self.send_response(200)
                self.send_header("X-Cache", "MISS")
                self.end_headers()
                self.wfile.write(resp.content)
                print(f"[SAVED] {path} cached at Edge.")
            else:
                self.send_response(resp.status_code)
                self.end_headers()
                self.wfile.write(f"Origin returned {resp.status_code}".encode())
                
        except requests.RequestException as e:
            print(f"[ORIGIN ERROR] {e}")
            self.send_response(502)
            self.end_headers()
            self.wfile.write(b"502 Bad Gateway: Origin Unreachable")

    def log_message(self, format, *args):
        pass # Suppress default logging


if __name__ == "__main__":
    port = 8080
    server = HTTPServer(("127.0.0.1", port), CDNEdgeHandler)
    print(f"CDN Edge Node running on port {port}")
    print(f"Origin Server: {ORIGIN_URL}")
    print("Test via:")
    print("  curl -i http://127.0.0.1:8080/json")
    print("  curl -i http://127.0.0.1:8080/uuid")
    
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        print("\nShutting down CDN node.")

Sample Output

# Terminal 1: Run Edge Node
$ python cdn_edge.py
CDN Edge Node running on port 8080

# Terminal 2: First Request (Cache Miss)
$ curl -i http://127.0.0.1:8080/uuid
HTTP/1.0 200 OK
X-Cache: MISS

# ... Terminal 1 Output:
[CACHE MISS] Fetching /uuid from Origin (https://httpbin.org)...
[SAVED] /uuid cached at Edge.

# Terminal 2: Second Request (Cache Hit - Instant!)
$ curl -i http://127.0.0.1:8080/uuid
HTTP/1.0 200 OK
X-Cache: HIT

# ... Terminal 1 Output:
[CACHE HIT] Serving /uuid from Edge (Age: 3s)

Note how the second request is blazing fast and doesn't hit httpbin.org at all.


8. Complexity

MetricCDNOrigin
LatencyExtremely low (<20ms). Edge is physically near the user.High (50ms - 300ms depending on distance).
Bandwidth CostLow (Fractions of a cent per GB).High (Cloud providers charge heavily for outbound data).

Scalability Characteristics

  • Dynamic Content Acceleration: Modern CDNs don't just cache static files. They can accelerate dynamic API calls by keeping long-lived, optimized TCP connections open between the Edge and the Origin (reducing TCP/TLS handshake latency).
  • Edge Computing: Cloudflare Workers or Lambda@Edge allow you to run Javascript/Wasm directly on the Edge nodes, entirely bypassing your Origin for basic business logic (like A/B testing or JWT validation).

9. Trade-offs

CDN FeatureProsCons
Pull CDNEasy setup. Infinite storage (only caches what's requested).First user takes a latency hit.
Push CDN100% Cache Hit rate. Zero latency for all users.Requires custom deployment scripts. Wastes storage if files are never requested.
High TTL (24h)Maximum offload from Origin. Fastest speeds.Very hard to fix if you accidentally cache a broken CSS file or sensitive data.
Low TTL (1m)Easy to fix mistakes rapidly.Constantly hitting the Origin. Defeats the purpose of the CDN.

10. Production Evolution

ConcernThis ImplementationProduction (Cloudflare / Fastly)
Cache StorageLocal Disk (Slow)NVMe SSDs + Massive RAM caches (LRU/LFU eviction).
RoutingDNS A-RecordAnycast BGP Routing. One IP address routes you to the physically closest datacenter globally.
SecurityNoneWAF (Web Application Firewall), DDoS mitigation, Bot protection, SSL Termination at the edge.
Cache HeadersHardcodedRespects Cache-Control: max-age=3600 sent by the Origin to determine TTL dynamically.

11. Common Bugs

BugWhat happensFix
Accidental Caching of Private DataOrigin returns a user's private banking JSON. The CDN caches it. The next user requests the same URL and sees someone else's bank account.Origin must send Cache-Control: private, no-store on all authenticated endpoints!
Query String BustingYou use /style.css?v=1. A proxy strips the query string, returning the old version.Use URL path versioning instead: /v1/style.css or /style.a8f9.css.
CORS failuresFonts/SVGs loaded from cdn.example.com fail to render on example.com due to browser security.Ensure Origin sends Access-Control-Allow-Origin: * and the CDN is configured to forward OPTIONS requests.

12. Interview Questions

  1. What is the difference between a Push CDN and a Pull CDN? Hint: Pull fetches from Origin on a cache miss. Push requires you to actively upload files to the CDN before they are requested.

  2. How does a CDN know when to delete a file from its cache? Hint: The Origin server includes a Cache-Control: max-age=X header in its HTTP response. The CDN respects this TTL.

  3. If you have a global user base, how do you ensure users in Japan hit the Tokyo CDN node, while users in Germany hit the Frankfurt node? Hint: Anycast DNS routing or Geo-DNS. BGP routing tables direct the packet to the topologically closest server announcing that IP.

  4. Your company accidentally pushed a broken JavaScript file to the CDN with a 1-year TTL. How do you fix the website for users immediately? Hint: Pushing an invalidation/purge command to the CDN takes time. The fastest fix is to push a code change to the HTML to request a new filename (e.g., app.v2.js).


13. Used By (Downstream Blocks)

  • 035 Edge Computing — Running code directly on CDN edge nodes.
  • 010 Caching Strategies — CDNs are essentially massive distributed caches implementing LRU/LFU.

14. Used In (Case Studies)

SystemCDN Strategy
NetflixUses their own proprietary Push CDN (Open Connect) placed inside ISP networks to serve massive video files.
InstagramHeavy reliance on CDN networks to serve billions of images and short videos globally.
TinyURLGenerally does not use CDNs for redirects, as redirects are highly dynamic, but might use them for the landing page assets.

15. Related Blocks

RelationshipBlock
Previous010 Caching Strategies
Next013 Database Indexing

16. Try It Yourself

Exercise 1: Respect Cache-Control

Modify the Python Edge server. When a Cache Miss occurs, inspect resp.headers.get("Cache-Control"). If the Origin returns no-store or private, do not save it to disk, but still return the content to the client.

Exercise 2: Purge Endpoint

Add an HTTP DELETE handler to the Edge server. When a request comes to DELETE /logo.png, delete the corresponding file from CACHE_DIR if it exists, simulating a CDN Cache Purge API.


Website Metadata

FieldValue
Hero TitleContent Delivery Network (CDN)
Hero SubtitleDefeat the speed of light. Serve static assets globally with millisecond latency using Edge caching.
BreadcrumbSystem Design → Building Blocks → CDN
Sidebar CategoryTier 1 — Core Backend Components
Search Keywordscdn, content delivery network, edge server, origin server, pull cdn, push cdn, anycast, cache invalidation, cache busting
Internal Links← 010 Caching Strategies · → 013 Database Indexing
Suggested IllustrationA map of the world. A massive, slow server in the middle (Origin). Lightning-fast mini-servers scattered across the continents (Edge Nodes) serving users instantly.
Suggested AnimationUser requests a file. Packet travels slowly across the ocean to the Origin. A copy is saved at the coastal Edge. The next user requests the file, and it instantly bounces back from the coastal Edge.
PreviousDatabase Indexing (B-Trees)NextCaching Strategies & Eviction (LRU/LFU)