The Lowdown on CDN Dynamic Content

cdn dynamic content

Typically when hear or read about a content delivery network, they are always talking about how your static assets (such as JavaScript, CSS, images) are being delivered from the CDN edge server’s cache. This is definitely a typical use case for a CDN. A common misconception though is that CDNs can’t handle caching dynamic content, which is not always the case. The term “dynamic” though might be a little different than what you think. Read more below about how CDN dynamic content works and how KeyCDN can help speed it up.

Static Content vs Dynamic Content

First off, it is important to note that we are not talking solely about static websites vs dynamic websites, even though they are very similiar, but rather the content that is on the page itself. Because there are ways to include dynamic content on a static website. Below are some common properties of static content and dynamic content.

Static Content

Static content is just what it sounds like, it is content that doesn’t change. Because of this, static content usually loads faster and has a smaller page size. It is content that doesn’t require any code to execute or make database queries. Also, it is fully cacheable. A good example of this is on Laravel’s website, which is just a straight HTML webpage with images, CSS, and JS linked to as static assets. There is no PHP or database queries being performed. It is made up of all static content.

Their webpage loads in under 400ms. Static content is fast!

Here are some common static file types:

  • Images: png, jpg, svg, gif, tif
  • Stylesheets: css
  • Javascript: js
  • Video and Audio: flv (Flash), mp4 (HTML5 videos), mov (QuickTime), wmv (Windows Media), mp3 and wav
  • Web Fonts: eot, ttf, otf, cff, afm, lwfn, ffil, fon, pfm, pfb, woff, svg, std, pro, xsf, and more…
  • Other Formats: pdf, doc, docx, ppt, pptx, xls, xlsx, epub, odt, odp, ods, txt, rtf, zip

Also, it is important to note that some popular CDN providers don’t cache files like mp3, mp4, zip, or rars, but KeyCDN does!

Dynamic Content

Dynamic content is content that is generated for you on the fly when you browse a webpage. WordPress is a good example of a CMS platform that has dynamic content. Dynamic content can be a lot more resource intensive because it can execute code and usually requires database queries to generate the content.

For example, when you visit a WordPress site, pretty much the entire page’s content is generated based on PHP and database queries. Below is an example of the stock index.php homepage page bundled with the WordPress twenty fifteen theme. It is originally 61 lines of code. But when someone visits it, it turns into 224 lines of code because of all queries and content being generated.

Caching CDN Dynamic Content

Dynamic content typically means that it is always changing and never the same. This could be anything from news articles which are being updated every few minutes, to stock prices, or even basketball scores and tickers on websites. This usually means that it can’t be cached. However, thanks to KeyCDN’s feature set, there are a couple options you have to cache things that are still frequently changing.

Option 1 – Pro-grammatically Purge with KeyCDN API

In the past, when it came to caching dynamic content on a CDN, some providers would just set the TTL lower. This means the visitor might not always see the latest version, but would at least see a close one. Thanks to KeyCDN’s instant purge technology you don’t have to worry about this. You can utilize KeyCDN’s API in your projects to purge the CDN cache when there should be triggers so that people see the latest dynamic content. A trigger is typically an action that occurs when a user or your webserver generates new content.

Option 2 – Purge By Tag

Another option you have is to purge by tag. Cache-Tags are assigned to cached content via a Cache-Tag response headers. These can be used to pro-grammatically purge only portions of cache, instead of flushing the entire cache. The tags must be defined via the Cache-Tag header from the origin server. You can add tags within the KeyCDN dashboard under “Zones” → “Purge by Tag.”

This can be a great combination to purge only sections of cache so that the dynamic content is always fresh.

Option 3 – Cache-Control Headers

When using a CDN, here is an example of what happens when a visitor comes to your website.

  1. Visitor hits website and requests a file from the CDN.
  2. CDN checks to see if it’s in cache.
  3. If the content hasn’t expired it is then served directly from the edge server to the client (HIT).
  4. If the content is not in the cache or expired, the edge server makes a request to the origin server to retrieve it (MISS).

With KeyCDN, you have the ability to modify the cache-control headers. Cache-Control is an HTTP cache header comprised of a set of directives that allow you define when / how a response should be cached and for how long. The parameter Expire adds or modifies the Expires and Cache-Control response header fields that are sent to the client if the response code equals 200, 201, 204, 206, 301, 302, 303, 304, or 307. The Expire value has only an impact on the web browser cache and not the edge server cache. You can find this under the “Advanced Features” on your zone in the KeyCDN dashboard.

keycdn cache-control headers

The following cases apply to this parameter if it has these values:

Cache-Control: no-cache
Push Zone: disabled
Pull Zone: as received from the origin (header honoring)
Cache-Control: max-age=t, where t is the time specified in the directive in minutes converted to seconds

Example can be seen below with the Expire directive set to 1440 (value in minutes which equals to 1 day):

curl -I
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 02 Nov 2016 04:48:02 GMT
Content-Type: image/png
Content-Length: 6396
Connection: keep-alive
Vary: Accept-Encoding
Last-Modified: Sat, 26 Apr 2016 12:11:29 GMT
ETag: "535ba271-18fc"
Alternate-Protocol: 443:npn-spdy/3,443:npn-spdy/2
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
Expires: Sun, 09 Nov 2016 04:48:02 GMT
Cache-Control: max-age=86400
Link: <>; rel="canonical"
X-Cache: MISS
X-Edge-Location: nlam
Access-Control-Allow-Origin: *
Accept-Ranges: bytes

The max-age value reflects the Expire directive in seconds (86400sec = 1440min).


So as you can see, there are ways to cache what some call dynamic content. By utilizing KeyCDN’s instant purge technology and API, you can setup triggers to purge cache when needed based on user or server actions. Also, using cache-control headers give you more flexibility when it comes to the client’s web browser cache. This allows you to still take full advantage CDN caching and ensure your visitors are seeing up to date information.

Related Articles

The Lowdown on CDN Dynamic Content was last modified: August 4th, 2016 by Brian Jackson
  • Nat Hobson

    Here’s my question: Is there a way to use the KeyCDN Cache Enabler plugin and then serve the static files from KeyCDN’s network. It seems like all the ingredients are there but I’m struggling with the execution side.

    Keep up the good stuff, apprcaite all the articles you guy put out :)

    • See the comment right above this one :) I think you are wondering how to serve like the HTML DOC load from KeyCDN cache? The plugin mentioned above isn’t an official KeyCDN plugin, but the developer definitely keeps it updated.

  • I wrote a plugin for WordPress that does exactly what this article describes You can run your entire site through KeyCDN and dynamic generated pages will be cached on KeyCDN’s edge servers sparing your origin server from excessive load from traffic spikes. I’ve hooked in to various WordPress events (aka actions) so when you update a post, the URL gets purged from KeyCDN and a fresh copy can be cached.

    A couple of gotchas I encountered:

    – If you’re trying to cache dynamic content and you keep seeing X-CACHE: MISS check to see if the page is being served in chunks. You’ll see an HTTP header of Transfer-Encoding: chunked if it is. You’ll need to ensure that the page is served all at once so KeyCDN can determine the content length and cache it. I did this using output buffering in PHP like this:

    – Serving your entire site through KeyCDN will strip out cookies which means you can’t login to the WordPress admin (which requires you to have a cookie set to verify that you are logged in). To get around this I set up an automatic redirect to pass wp-admin requests to the origin URL, not the URL that is going through KeyCDN. So if is your origin and goes through KeyCDN, going to will redirect you to and everything else will work.

    – To ensure repeat visitors see the freshest version set the CACHE-CONTROL header with a max-age value to something real low like 5. This means the browser will only cache the page for 5 seconds. After which it will ask KeyCDN for a fresh copy. Setting the max-age to 0 will prevent the page from being cached at all by both the browser and KeyCDN. To tell KeyCDN to hold on to that copy of the page serve a CACHE-CONTROL header with a s-maxage = 86400 aka 24 hours. In the end you want to see this in your HTTP headers: Cache-Control: max-age=10, s-maxage=86400, public

    Use to check!

    • And I also base a WordPress plugin , it’s a alternative choice.

      An example site:

    • thbt

      Why do you suggest only a 5-10 second cache control setting? Or do you mean just for pages that are likely to get updated frequently? For pages that don’t often change, like our static home page, we let browsers cache it for a few days (the user login info at the top of the page is displayed dynamically with Javascript).

      • The HTML page cache for browser needn’t cache by browser for a long time, because you cannot purge the cache for the browser, if you update a page, some visitor might see the new pages after a day. And KeyCDN support the e-tag and 304 header, that header will tell the browser the content doesn’t change, so browser will not download the page again when cache is expired.

      • You could set the max-age to whatever value your comfortable with. Many people set it very low so they ensure that when someone visits a page they get the most recent version. If your max-age is set to 24 hours and the page was changed for the past 24 hours there could be confusion.

        There is more benefit to keep the max-age low then there is potential downsides as the page is cached on the CDN and served very quickly, closer to the visitor, and is a small file size. If you set a high max-age you’re pretty much stuck waiting until it expires. There’s not much else you can do short of telling a visitor to do a hard refresh or to clear their browser cache.

  • thbt

    This would work with many CDNs, but if you use KeyCDN, you can’t as easily cache dynamic content, including content from PHP. Even the HTML of the home page, specifically mentioned in this article, can’t really be cached by KeyCDN! (But it would work with fine with some other CDNs.)

    The reason is KeyCDN has a peculiar issue where it refuses to cache content that doesn’t have a “content-length” HTTP header. And dynamic content doesn’t normally have that header. There are work-arounds where you can add special code to your PHP or Laravel project to add the content-length header. The comment by kingkool68 also mentions a work-around for WordPress.

    There’s no reason KeyCDN couldn’t fix their software to stop refusing to cache content without a content-length header. Hopefully they’ll fix it some day. Meanwhile, you’ll have to either use a different CDN, or use a special work-around to add content-length headers to your content.

    • Ha! This is true. The Transfer-Encoding: Chunked issue did have me scratching my head a little bit. Dealing with this issue isn’t that hard once you’re aware of it. I had to open a support ticket to find out myself.

      At the end of the day, KeyCDN makes running my personal sites through a CDN attainable where other CDNs have a monthly minimum price or are waaaay too expensive. The next best choice that I played around with was SoftLayer’s CDN which is actually powered by EdgeCast. It was twice the price and not nearly as intuitive or feature rich as KeyCDN. I think it’s a fair compromise that you have to do a slight tweak to run dynamic content through the CDN.

      Some might consider this a feature as they can run their whole site through the CDN, static assets will be cached, and page requests will be sent to the origin. It reduces the complexity of needing a second domain plus it’s a brain-dead easy way to get your whole site on TLS/SSL without having to do anything on your backend.

      • thbt

        I agree that KeyCDN is great aside from this issue. Ideally they would make it an option so you can choose whether or not to make the cache ignore chunked encoding without content-length.

    • Just checked some PHP and ASP.NET sites and they return “content-length” so I wouldn’t say the don’t normally have that header.

Share This