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?
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.