Without a CDN, every user crosses the planet

With one server holding the only copy, every request reaches that one box and pays the full propagation cost — adding users multiplies the load on that box, but it never shrinks the distance any one user has to cross.

Previously

The map ended at a single origin reached by a long trip; before we add any caches back, feel exactly how expensive that trip is when every user in the world has to make it.

Scene 01

Without a CDN, every user crosses the planet

  1. Watch
  2. Try it
  3. Predict
  4. Capture
users 3 · in-flight 3WITHOUT A CDNRTT 245 msRTT 95 msRTT 130 msORIGINus-eastORIGIN RPS6 / 8001São Paulo1Frankfurt1SydneyPER-REGION p50 LATENCY (more users does NOT shrink these bars)São Paulo1u130 msp50ocean-boundFrankfurt1u95 msp50near originus-east0u8 msp50near originMumbai0u220 msp50ocean-boundSydney1u245 msp50ocean-boundevery user is one ocean away from the only copy of the content
One origin in us-east. Every user — wherever they live — pays the full ocean-crossing round trip to reach it. That round trip is the RTT.
What to watch for

Three users — one in São Paulo, one in Frankfurt, one in Sydney — all firing requests at the same single server in us-east. Watch the request arcs visibly cross oceans and the time it takes for the request to travel there and the reply to come back, which we'll call the round-trip time (RTT), settle into the 100-250 ms range. The server above the map is the one authoritative source for every request; its load gauge climbs as more requests arrive.

Continue unlocks when the animation finishes.
Implementation

Highlighted lines are the ones running in the diagram right now.

Client.request
what every browser does when there is no cache in front
def request(url):
# DNS resolves to the one origin in us-east
origin_ip = dns.resolve(origin_host)
# one TCP+TLS handshake, then the GET — each
# leg of the trip costs (distance / c) milliseconds
conn = tcp.connect(origin_ip) # 1 RTT
conn.send(http.get(url)) # 1 RTT
response = conn.recv() # waits here
return response # total wait ~= rtt_to(us-east)
Origin.serve
the one box every request in the world ends up at
rps_counter = 0 # what the gauge above the box reads
def serve_forever():
while True:
conn = listener.accept() # next user, anywhere
rps_counter += 1 # +1 per arriving request
req = conn.recv()
body = storage.read(req.path) # no cache layer
conn.send(http.ok(body))
conn.close()
rtt_to(region)
what the per-region latency strips are actually computing
# Set by physics, not by how busy the origin is.
# Cross-ocean ~150 ms, cross-continent ~80 ms,
# nearby ~30 ms (HPBN, ch. 1).
def rtt_to(user_region):
distance_km = great_circle(user_region, ORIGIN)
propagation = distance_km / SPEED_OF_LIGHT_IN_FIBER
return 2 * propagation # there AND back
# Notice: user_count does not appear anywhere here.
# Adding users cannot shrink any one user's trip.

Where this sits in Build a CDN

Scene 01 of 13, in the Edge basics act — The request journey, origin pain, an edge near each user, POPs and anycast.. One origin, three continents, and the cost: every user pays full cross-ocean RTT and origin RPS scales with your user count.

Up next. One box can't sit close to every continent at once, so the only way to make every user fast is to put a copy of the content near each user — which is exactly what the next scene introduces.

All 13 scenes in Build a CDN · Every curriculum

Built with Arqly
Every scene in Build a CDN builds on the one before it.All 13 Build a CDN scenes