Push vs. Pull CDN
In one line: this is the most commonly asked CDN question in interviews, and the strong answer is neither "push" nor "pull" — it is knowing which content type each suits and saying so.
Push CDN
The origin server automatically sends content to the proxy servers. The content provider is responsible for managing this delivery.
- Best for: static content, where the origin server decides exactly what to deliver.
- Drawback: inefficient for rapidly changing content, often resulting in redundant pushes — you ship a new version to every edge whether or not anyone requests it.
Pull CDN
The CDN fetches data from the origin only when a user requests it. Proxy servers then cache the file for a specified time-to-live to balance capacity and cost.
This model is ideal for dynamic content or high-traffic sites where pre-loading all assets is inefficient.
The comparison
| Push CDN | Pull CDN | |
|---|---|---|
| Who initiates | Origin server | First user request |
| Who manages delivery | The content provider | The CDN |
| Replicas maintained | More — improving availability for static content | Fewer — only what's been requested |
| Storage consumption | Higher | Lower |
| First request latency | Fast — already there | Slow — a cache miss reaches origin |
| Frequently changing content | Poor — redundant pushes | Good |
| Best for | Static assets, predictable catalogues | Dynamic content, high traffic, large catalogues |
In short: Push CDN maintains more replicas, improving availability for static content. Pull CDN is favored for frequently changing content and high traffic loads due to lower storage consumption.
Worked example: a website with two content types
A common interview framing. You manage a site with:
- News feed — frequently updated articles and blog posts with varying popularity.
- Static assets — the company logo, design elements, product images. These change infrequently.
| Content type | Choice | Justification |
|---|---|---|
| Static assets | Push | Small, stable, known in advance, and needed by essentially every page load. Pushing guarantees the first visitor in every region gets a cache hit, and the redundant-push drawback doesn't apply because they rarely change. |
| News feed | Pull | Frequently updated and unevenly popular. Pushing every article to every PoP would waste storage on posts nobody reads, and each edit would trigger another redundant push. Pull fetches only what's actually requested, with a short TTL so updates propagate. |
Pull's cold-start problem
With pure pull, the first request in each region pays a full origin round trip — exactly the latency the CDN exists to eliminate. For a viral launch that means the first user in every PoP gets the worst experience, simultaneously, at the moment you most want things to go well.
The mitigations are cache warming (pre-fetching before a known event, which is push in disguise) and tiered caching from Lesson 6, where an edge miss hits a regional parent rather than the origin.
Key takeaway
Push when you know what will be wanted and it rarely changes. Pull when you don't, or it does. Real systems split by content type — and the hybrid is the correct answer, not a hedge. And both models depend on the cache key to decide what counts as the same object — which fails in both directions: too much in the key (tracking parameters) collapses the hit rate on byte-identical files, and too little serves one user's personalised page to another. Normalize the key to an allowlist, and keep anything that depends on who is asking out of the shared cache.
What counts as "the same object"?
Both push and pull assume the edge can tell whether it already has what was asked for. That judgement is made by the cache key, and it is the single most consequential piece of CDN configuration — because it fails badly in both directions.
By default the key is roughly the URL. The interesting question is what else goes into it, and what gets left out.
Too much in the key destroys the hit rate
Marketing links carry tracking parameters. logo.png?utm_source=twitter and logo.png?utm_source=email are the same bytes, but if the whole query string is in the key they are two objects — and with enough campaigns, thousands.
/logo.png -> cached /logo.png?utm_source=twitter -> MISS, fetched again /logo.png?utm_source=email -> MISS, fetched again /logo.png?fbclid=xyz789 -> MISS, fetched again
Every one of those is a full origin fetch for a byte-identical file, and the hit rate — the number the entire CDN exists to move — quietly falls while everything appears to work.
The fix is key normalization: keep an allowlist of parameters that genuinely change the response, drop the rest, and sort what remains so ?a=1&b=2 and ?b=2&a=1 produce one key rather than two.
Too little in the key is a security incident
The opposite mistake is worse, and it is the one that ends up in a postmortem.
If a response varies by a request attribute that is not in the key, the edge cannot distinguish the variants — so it stores whichever it saw first and serves it to everyone.
That is cache poisoning by misconfiguration, and no attacker is required. The same shape appears with language, currency, device class, and A/B test buckets: a response that depends on something absent from the key will be served to the wrong audience.
Two defences, and they are different in kind. The response can declare the headers it varies on — a Vary header — so the edge keys on them automatically. And, far more reliably, anything personalised should be marked private and not cached at the edge at all. The rule worth carrying: if a response depends on who is asking, the safe default is not to cache it — and if you do, the thing that identifies them must be in the key.
The judgement
The tension is real and unavoidable: the more precise the key, the safer and the less effective. A key that includes everything is always correct and caches nothing useful.
So the practical discipline is to be deliberate rather than default: start from path-only, add exactly the parameters and headers that change the bytes, and treat every addition as a hit-rate cost you have chosen to pay. And keep personalised responses out of the shared cache entirely, where the question does not arise.
Interview signal by level
| Level | What a strong answer sounds like |
|---|---|
| L4 | Defines both: "push sends content ahead of time, pull fetches on first request." |
| L5 | Chooses per content type: "push the static assets since they're stable and universally needed, pull the articles since most are rarely read." |
| Staff+ | Names the deciding property and the failure mode: "the question is whether demand is predictable. And pure pull has a cold-start problem — the first user in every region eats an origin round trip at launch, so I'd warm the cache for known events and use tiered caching so a miss hits a regional parent, not origin." |
Next: content that can't simply be cached.