Why isn't a CDN working as it's supposed to be?

164 Views Asked by At

I'm always confused by CDNs and whether they're doing their job effectively.

I know that in theory, their purpose is to shorten the latency between the server and the user.

However, I usually like to test things before I try. So I uploaded an image to imgur.com and then tested the speed of the image file on 2 sites:

First test: https://tools.keycdn.com/performance

Second test: https://tools.pingdom.com

I've selected New York as the testing location on the second website. So I hit test on the first one - it gave me about 200-300ms latency on New York. Then I hit test on the 2nd website and it also gave me a quite high latency like 300ms or so.

When I hit test the 2nd time it lowered down to 15-30ms of course because that's what a CDN should do.

The question is though that those 2 servers were in the same location, but it looks like the image didn't get cached at all. Why is this happening or what am I missing here? I thought if it's cached then it should already reduce the latency to ANY other requesting server/user in that area. Am I wrong?

1

There are 1 best solutions below

0
On BEST ANSWER

A CDN besides trying to deliver your content fast (shorten the latency) can help you also to protect/secure your origin by not exposing it directly, check this post for an introduction about other benefits: what is a CDN?

Regarding your test, there are many factors involved, for example, all new content (MISS) always will take more time to be served since it hasn't been cached, that content that as being already pre-fetched and cached (HIT).

You could start by checking the headers, for example in a terminal run this:

$ curl -I https://immortal.run/img/immortal.png

You may see an output like this:

HTTP/2 200
date: Fri, 17 Aug 2018 07:51:20 GMT
content-type: image/png
content-length: 6757
set-cookie: __cfduid=d0be8792ec1e81d223eaa9e05b780a8fa1534492280; expires=Sat, 17-Aug-19 07:51:20 GMT; path=/; domain=.immortal.run; HttpOnly
last-modified: Thu, 07 Jun 2018 20:20:47 GMT
access-control-allow-origin: *
expires: Fri, 17 Aug 2018 11:51:20 GMT
cache-control: public, max-age=14400
x-github-request-id: 47B0:1A82:37CB24D:4D9A0A9:5B752825
cf-cache-status: HIT
accept-ranges: bytes
strict-transport-security: max-age=15552000; includeSubDomains; preload
x-content-type-options: nosniff
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 44ba8e10cb6597aa-FRA

Notice the header:

cf-cache-status: HIT

When the resource has been cached and served from the CDN it will be HIT if not it may be MISS, here you can see a list of more possible responses that apply to Cloudflare: https://support.cloudflare.com/hc/en-us/articles/200168266-What-do-the-various-Cloudflare-cache-responses-HIT-Expired-etc-mean-

Now to test how fast a resource is loading you could use curl, Depending on your shell you may want to add the next function curl_time() into ~/.profile, ~/.zshrc or ~/.bashrc

curl_time() {
    curl -o /dev/null -Ls -w " \
        time_namelookup:  %{time_namelookup}\n \
        time_connect:  %{time_connect}\n \
        time_appconnect:  %{time_appconnect}\n \
        time_pretransfer:  %{time_pretransfer}\n \
        time_redirect:  %{time_redirect}\n \
        time_starttransfer:  %{time_starttransfer}\n \
        ----------\n \
        time_total:  %{time_total}\n" "$1"
}

Then give a try with something like this:

$ curl_time https://immortal.run/img/immortal.png
         time_namelookup:  0.133057
         time_connect:  0.144885
         time_appconnect:  0.200092
         time_pretransfer:  0.200299
         time_redirect:  0.000000
         time_starttransfer:  0.416685
         ----------
         time_total:  0.418580

In my subsequent requests, I got it delivered faster time_total: 0.093495:

$ curl_time https://immortal.run/img/immortal.png
         time_namelookup:  0.004583
         time_connect:  0.019833
         time_appconnect:  0.067715
         time_pretransfer:  0.067839
         time_redirect:  0.000000
         time_starttransfer:  0.091393
         ----------
         time_total:  0.093495

If just want to get the total_time repeditely you could try this:

$ for i in {1..3}; \
curl -sL -w "%{time_total}\n" -o /dev/null https://immortal.run/img/immortal.png

Analyzing the headers and the response times is a good start point for checking how the CDN is behaving.