The most surprising thing about purging CDN cache is that you can’t truly "purge" it; you can only "invalidate" it, and the difference is critical for avoiding downtime.

Imagine a user requests https://example.com/image.jpg. Your CDN edge server might have a cached copy. When you want to update that image, you can’t just tell the edge server, "delete that file." Instead, you tell it, "this file is now stale; the next time someone asks for it, go back to the origin server and get the new version." This invalidation process takes time to propagate across the CDN’s global network. If you then immediately try to access https://example.com/image.jpg from a different edge server that hasn’t received the invalidation signal yet, you’ll still get the old image. This is the root of "stale content" issues.

To avoid downtime and serve the correct content immediately after an update, the standard practice is to combine cache invalidation with a versioned URL strategy.

Here’s how it works in practice. Let’s say your original URL is https://cdn.example.com/assets/styles.css.

  1. Initial Deployment:

    • You upload styles.css to your origin server.
    • Your web application serves it at https://cdn.example.com/assets/styles.css.
    • The CDN caches this.
  2. Content Update:

    • You modify styles.css and save it as styles.v2.css on your origin server.
    • Crucially, you update your web application’s HTML to reference the new file: <link rel="stylesheet" href="https://cdn.example.com/assets/styles.v2.css">.
    • You don’t invalidate the cache for /assets/styles.css (which now points to the old file).
  3. New Users Get New Content:

    • New users requesting https://example.com/ will get the updated HTML, which points to styles.v2.css.
    • The CDN edge server for these new users will see styles.v2.css is not in its cache. It will fetch styles.v2.css from your origin and serve it. This is a cache miss, but it’s expected and results in the correct content.
  4. Old Content Eventually Expires:

    • Users who previously had https://cdn.example.com/assets/styles.css cached will continue to receive the old version until their cache TTL (Time To Live) expires.
    • Once the TTL for styles.css expires on an edge server, that server will perform a cache miss on its next request for styles.css, fetch the new styles.css from the origin (which is now the old styles.v2.css), and serve that. This is where the old URL eventually serves new content.

This versioning strategy ensures that any user making a new request after the deployment gets the correct, updated asset immediately, while existing users gradually receive the updated content as their cache TTLs expire. There’s no moment where a user might receive an inconsistent state.

Let’s look at a practical example using a common CDN provider’s API (syntax will vary, but the concept is identical).

Suppose you are using Cloudflare. You’ve deployed a new version of your main JavaScript file.

Original URL: https://cdn.example.com/app.js New URL: https://cdn.example.com/app.1a2b3c4d.js

Your HTML would change from:

<script src="https://cdn.example.com/app.js"></script>

to:

<script src="https://cdn.example.com/app.1a2b3c4d.js"></script>

You would not typically run a cache purge command for /app.js immediately. Instead, you’d let its TTL expire naturally. If you needed to force older clients to get the new version faster, you’d use an invalidation API call, but the versioned URL is the primary mechanism for zero-downtime deployments.

Here’s how you might invalidate a specific file using Cloudflare’s API (after deploying the new version and updating your HTML):

curl -X DELETE "https://api.cloudflare.com/client/v4/zones/<ZONE_ID>/purge" \
     -H "X-Auth-Email: <EMAIL>" \
     -H "X-Auth-Key: <API_KEY>" \
     -H "Content-Type: application/json" \
     --data '{"files": [{"url": "https://cdn.example.com/app.js", "recursive": false}]}'

This command tells Cloudflare to remove app.js from its cache. The recursive: false means it only purges that exact path. The recursive: true option would purge everything under that path, which is usually too aggressive and can lead to performance issues as the CDN has to refetch many assets.

The recursive: false flag is important. Using recursive: true on a path like /assets/ would tell the CDN to invalidate everything under /assets/, which could be hundreds or thousands of files. This forces the CDN to go back to your origin for every single one of those files, potentially overwhelming your origin server and making subsequent page loads much slower for users until the cache repopulates. The versioned URL strategy avoids this by only ever creating new cache entries and letting old ones expire.

The actual mechanism by which an edge server knows to fetch a new version when a URL changes is straightforward: it’s a cache miss. When a request arrives for app.1a2b3c4d.js and the edge server doesn’t have it, it checks its cache. If it’s not there, it’s a cache miss. The edge server then goes to the origin server to retrieve app.1a2b3c4d.js, caches it, and serves it to the user. This is the desired behavior. The complexity arises when you want to update content served at a static URL that many clients might have cached.

When you use the purge API with recursive: false for a specific file like app.js, you’re essentially forcing a cache miss for that exact URL. The next request for app.js will go to the origin. If you’ve already deployed the new version of your application to serve app.1a2b3c4d.js, this purge command is a way to clean up the old, now-unused app.js from the CDN’s edge, ensuring it doesn’t linger if a user’s browser somehow still requests it. It’s a cleanup step, not the primary deployment mechanism.

The core idea is that you are always adding new, versioned resources to your CDN and origin, and your application’s HTML/logic is updated to point to these new resources. The old resources are implicitly retired by not being referenced anymore. Cache invalidation is a tool to speed up the removal of old resources from the CDN, but it’s secondary to the versioning strategy for ensuring users get the correct content immediately.

The next challenge you’ll face is managing cache TTLs effectively for assets that don’t change frequently but might need occasional updates without re-versioning everything.

Want structured learning?

Take the full Cdn course →