A Practical Guide to Cache Purge: From Cache Keys to Variant-Level Purging
Purged the cache but still getting hits? Most of the time the answer lies in the cache key. How Yeap CDN builds cache keys, how query-string modes work, and exactly what a URL purge removes with and without a query string.
"I purged the cache, so why am I still seeing old content?" It is one of the most common questions CDN users ask, and the answer almost always comes down to the cache key: the object you purged and the object visitors are hitting may not be the same one. This guide starts with cache keys, then explains exactly what a purge on Yeap CDN removes and how we deliver purge requests behind the scenes.
Cache keys: how the edge tells files apart
When an edge node caches a response, it identifies it with a cache key. Roughly, the key is made of:
- the hostname, for example
www.example.com; - the path, for example
/assets/app.js; - the normalized query string, depending on the query mode configured for the domain;
- and, where relevant, variant dimensions such as content encoding.
Two requests hit the same cached object only if their keys are identical. That is why /app.js?v=1 and /app.js?v=2 are separate objects by default, and why a version parameter makes both browsers and the CDN fetch the new file.
Query-string modes
On the CDN → Domains → Cache page in the console you can choose how a domain treats query strings. The page also shows a live cache key preview for the current settings:
| Mode | Behavior | Good for |
|---|---|---|
| Standard (full) | All parameters are part of the key; ?a=3 and ?a=4 are two objects | Sites where parameters change the content |
| Ignore | Query strings are ignored entirely; every combination hits the same object | Purely static assets |
| Sorted | All parameters are included after sorting by name; ?b=2&a=1 and ?a=1&b=2 share an object | Clients that send parameters in varying order |
| Allowlist | Only the listed parameters are part of the key | When only a few parameters change the content |
| Denylist | The listed parameters are excluded; everything else is included | Ignoring tracking parameters such as utm_source |
Under the hood the edge always decodes parameters, sorts them by name (and sorts repeated values of the same name), then re-encodes them before building the key. So in any mode that keeps parameters, ordering never creates duplicate objects. The re-encoding step matters too: it ensures that an & or = inside a decoded value cannot produce an ambiguous string, so two different requests can never collapse onto the same cache key.
A common optimization: marketing links often carry assorted tracking parameters, and every distinct combination creates a new object, diluting your hit ratio. Excluding them with the denylist mode usually improves the hit ratio noticeably.
What a purge actually removes
Click Purge cache in the top right of the cache settings page and choose one of two options.
Purge everything
Removes every cached object for the domain on all edge nodes. Use it for major releases or when you are not sure what changed. The cost is that for a while afterwards every request goes to your origin, so origin load rises briefly.
Purge by URL
Enter one full URL per line. These rules are the key to understanding purge behavior:
- Without a query string, for example
https://www.example.com/list: removes every query-string variant of that path, including/list,/list?page=2,/list?page=3and so on. - With a query string, for example
https://www.example.com/list?page=2: removes only that one variant;/list?page=3stays cached.
When you purge with a query string, it is normalized with exactly the same rules used to build cache keys (same mode, same sorting and encoding). So even if the cached request was ?b=2&a=1, entering ?a=1&b=2 purges it precisely.
We built this behavior in response to user feedback. An early version of the purge index compared only host and path, so purging ?a=3 could report success while the object kept hitting, because the cache key included the query string and the purge match did not. Every purge index entry now records its normalized query string, and purges match at the variant level.
The edge's purge model also supports prefix, wildcard and tag matching; the console currently exposes full-site purge and purge by URL.
How purge requests reach every node
When you confirm, the console returns almost immediately, because the purge is not delivered synchronously inside your HTTP request:
- The control plane places the purge job (domain plus list of paths) on a Redis-backed background queue and returns right away.
- Queue consumers deliver the job in parallel to the edge nodes serving that domain, with automatic retries on failure.
- If the queue itself is unavailable, the control plane falls back to synchronous delivery, so a purge is never lost.
On an edge node, a complete purge has two parts: find every matching storage key in the purge index, then evict those objects from cache storage and clear them from the in-memory hot tier. To keep multiple delivery channels from interfering with each other, only the channel that can reliably evict from storage in an async context modifies the index. The others perform a non-destructive match that clears the hot tier and leaves the index alone. Whichever channel arrives first, the purge ends up complete.
How to verify
Edge responses include an X-Cache-Status header. After purging, check with curl:
curl -sI "https://www.example.com/list?page=2" | grep -i x-cache-status
# first request after the purge: X-Cache-Status: MISS
# request again: X-Cache-Status: HIT
If you still see old content after a purge, check in this order:
- Is it the browser cache? An edge purge does not touch copies already cached in visitors' browsers. Test with curl or a private window.
- Does the URL you entered use the same hostname as the real request?
example.comandwww.example.comare different caches. - Is your origin still serving old content? After a purge the edge goes back to the origin, so if there is another cache in front of your origin, it needs refreshing too.
Best practice: rely on purge as little as possible
Purge is a useful tool, but for static assets the most reliable approach is to let the URL change with the content:
- Use content-hashed filenames such as
app.3f9a1c.jsand give them long cache lifetimes. A new version is a new URL, so nothing needs purging. - Give HTML entry pages a short cache lifetime so they pick up new asset URLs quickly.
- When you do need to purge, prefer purge by URL, and save full-site purges for broad changes.
Once you understand the cache key, purging stops being guesswork: whichever key you purge is the key that goes away.
Build on Yeap Cloud
Free DNS and CDN plans for every new account.
Keep reading
Yeap CDN's new edge: why we chose Rust
We replaced our CDN edge with a new in-house version built in Rust on Pingora. Here is what it means for your site: faster connections, configuration that applies in seconds, and stronger isolation and security.
Getting Started with the Yeap LLM API Using the OpenAI SDK
The Yeap LLM API is OpenAI-compatible: keep your SDK and point base_url at https://llm.yeap.cloud/v1. Covers creating a key, Python and Node.js examples, streaming, embeddings, and per-key quota, model and IP limits.
Put Your Website Behind Yeap CDN with Free HTTPS in 10 Minutes
A step-by-step walkthrough for putting an existing site behind Yeap CDN: add the domain, configure the origin, connect via CNAME or NS, get a free Let's Encrypt certificate, choose an SSL mode, force HTTPS, and verify with curl.