(Note: after seeing stern feedback on Hacker News and reddit, I’m changing my test approach to hire 10+ contractors in popular cities around the globe to compare CDN download times. And if you disagree with my analysis in any way, please cordially do so 😊. I’m on twitter at @SpeedTestDemon)
I’ve learned Cloudinary basically does image and video transformations on top of the Fastly CDN. As such, I feel this is basically a review of the Fastly CDN platform. Fastly costs minimum $50/month, so it’s not free CDN I’m interested in analyzing. However, Cloudinary has a free tier going up to 25 GB of storage or bandwidth, so here’s “Analysis #2 of a Free CDN”.
Cloudinary was SUPER impressive. Cloudinary was way better than AWS CloudFront. They had a secret sauce: dramatic image transformation. Cloudinary somehow compressed a 703 KB image down to 37 KB.
Before I present the simplified summary, here are some links relevant to this article.
Cloudinary had better performance for several reasons:
What follows is a much more detailed technical analysis.
I had to do 2 speed tests. The 1st speed test was not apples-to-apples because Cloudinary had compressed the image by nearly 95%. The 2nd speed test, I controlled for file size, and this time Cloudinary came out ahead very slightly by 6% (although the main credit should be due to Fastly).
In the first speed test, Cloudinary really crushed CloudFront.
At first sight, I had to double-check for errors. Cloudinary was nearly 3x faster — on the hot cache! — and it didn’t make sense. Turns out the test was correct. Cloudinary simply compressed the image 95% lower (700 KB to 36 KB).
I had to do a second speed test to make it more apples-to-apples between CloudFront and Cloudinary (masquerading as Fastly). CloudFront did a lot better in the hot cache. Still sucked at the other two metrics.
There were several reasons for Cloudinary performing so well:
OK Cloudinary’s free tier is pretty impressive. The only limitation I can think of is you can’t host your whole site on it like you can with Cloudfront.
Now one moment…you do “get what you pay for”…while Cloudinary has great performance, it is limited in many other ways. You can’t update a file on Cloudinary easily, unless you wholesale rename the file (very annoying). The amazing performance applies mainly to images. JS and CSS won’t have the same amazing image compression, although you will see Cloudinary perform on par with CloudFront.
See the conclusion for my thoughts on the Cloudinary vs CloudFront decision.
It should be noted that not every free CDN performs as well as Cloudinary. I found a couple free CDNs that performed really poorly.
Honestly, it was just because they had a free tier CDN and my goal here was just to test every free CDN.
I didn’t know anything about Cloudinary before writing this article.
But wow, the results have blown my mind. Good job Cloudinary guys! These guys have a good product.
After doing some more research on Cloudinary, I found out these guys have won some interesting accolades
OK, so it’s got a reputation for great image management. I can see that actually. They did insanely well in this test.
Because Amazon is Amazon and they’re the biggest cloud provider out there (they are #1 at 32% of the market). But Cloudinary’s impressive speed test results here have me really questioning why I’m using CloudFront. Well Cloudinary’s premium tier is very expensive at $100/month, so it’s not an obvious switch. CloudFront is only at $2/month for the equivalent network out.
We are interested in the hot, cold, and warm cache speeds because CDNs are essentially a cache layer. If you’re interested in reading more, see the analysis here: metrics measured in Jetpack vs CloudFront and my CDN testing methodology.
This was similar to what I found in Jetpack CDN vs Cloudfront. Cloudinary is able to achieve a significantly faster lookup time because it’s DNS path is more likely to be cached by the intermediate routers. Cloudinary DNS lookup path is “res.cloudinary.com” which seems to be the shared DNS path between most Cloudinary users, so that DNS lookup path is receiving a lot of traffic.
While CloudFront’s DNS lookup path is a very customized “d20zaq59cm4c4j.cloudfront.net”.
What’s very interesting is Jetpack CDN’s DNS lookup times were always nearly as fast as the hot cache’s DNS lookup time (even the cold cache 0.00223 seconds was so close to hot cache 0.0016 seconds), while Cloudinary’s DNS lookup times took a small hit (hot cache 0.00175 seconds to warm cache 0.0236 seconds). I think this can be attributed to Jetpack CDN’s immense popularity which means its DNS lookup path “i0.wp.com” is going to be cached much more frequently than Cloudinary.
I’m not exactly sure Cloudinary got it so good. The same 703 KB image was somehow compressed down to 36 KB. That’s just really good and explains how Cloudinary was able to get much faster Data Transfer times than CloudFront.
I already talked about these in previous essays ( Jetpack CDN vs CloudFront) so I didn’t want to write more paragraphs for these.
The first time I ran this comparison test, I was blown away by how good Cloudinary was. I thought Jetpack CDN was a good Image CDN. I was wrong. Cloudinary was way better.
CloudFront really lagged horribly here at 2.355 vs 0.395 seconds for Cloudinary.
Sharp readers will notice that CloudFront showed a much worse time (2.355 seconds) in this speed test comparison than in the Jetpack CDN vs CloudFront analysis (1.199 seconds). It’s because I just ran this CloudFront download at a different time than when I wrote the Jetpack CDN analysis.
Wait a second. CloudFront took 2.35 seconds while Cloudinary was only 0.39 seconds? Holy moly. Where did all that time go?
The two big time consumers were: 1) Request Latency, and 2) Data Transfer.
Regarding Request Latency: CloudFront took 1.022 seconds while Cloudinary took 0.258 seconds. What’s impressive is Cloudinary must have done two things during the cold cache lookup: it must have had the file still cached on a server despite my asking for the file only several days after getting that CDN setup. Cloudinary certainly did not fetch the file again, or it wouldn’t have gotten such a fast time. That’s really really good.
Cloudinary’s cold cache is not as fast as its hot cache. Most of the time went in Request Latency. For cold cache, it’s likely they had the file stored somewhere on disk, while for hot cache, it’s probably in RAM. Actually, since Cloudinary is built on top of Fastly, I would place a strong bet that Fastly has the file in RAM or else why are people buying Fastly?
Regarding Data Transfer: yeah this was really incredible. Cloudinary only needed 0.0069 seconds while CloudFront took 1.098 seconds. There’s only one main factor for this and it’s Cloudinary’s insane image compression algorithm which means Cloudinary only has to send 36 KB while CloudFront has to send 703 KB. It’s just not even close. See more analysis in Finding #2.
Regarding SSL handshake: honestly not sure why CloudFront took much longer at 0.091 seconds vs 0.056 seconds but the absolute difference is only 0.035 seconds, so it’s a small contributor to the overall delta of nearly 2 seconds.
Regarding TCP handshake: this is just the same for any connection. So there’s not a big absolute time delta.
Regarding DNS lookup: not the biggest factor for the large overall time delta but it’s still worth mentioning because on a relative basis, Cloudinary outperformed by over 100% (0.0494 seconds vs 0.124 seconds). See Finding #1 analysis for why Cloudinary’s DNS lookup is generally much faster than CloudFront.
This hot cache measurement was the one that really blew my mind.
Cloudinary smokes Cloudfront, nearly 3x faster (0.133 vs 0.397 seconds).
Wow! How did Cloudinary do that?
(Reminder: these times are an average of 10 curl calls).
Looks like all the times are pretty similar except for Data Transfer. In fact, Data Transfer accounts for 0.234 seconds of the overall time difference of 0.263 seconds. Literally about 90%.
It’s really shocking that CloudFront took so much longer to transfer the file, even in a hot cache state.
The reason is Cloudinary compressed the original 700 KB file down to 36 KB. That’s nearly a 20x reduction in file size. So no wonder Cloudinary ended up smoking the pants off CloudFront.
Notes:
Ouch. CloudFront nearly 4x slower than Cloudinary: 0.465 vs 0.126 seconds.
What happened?? (reminder: warm cache is download taken exactly 30 minutes after hot cache)
First off, a monstrous Data Transfer difference: Cloudfront 0.198 seconds vs Cloudinary 0.009 seconds. Absolute difference of 0.19 seconds, contributing to the overall time difference of 0.34 seconds.
Second, a monstrous DNS lookup difference: Cloudfront 0.115 seconds vs Cloudinary 0.0236 seconds. Absolute difference of 0.09 seconds, contributing to the overall time difference of 0.34 seconds. If you thought DNS lookup speeds don’t matter — well think again. See “Finding #1” for why CloudFront’s DNS lookup is so much slower than Cloudinary.
Data Transfer and DNS lookup combine for 0.28 seconds out of the 0.34 seconds difference.
Other notes:
Cloudinary beat CloudFront in hot cache, cold cache, and warm cache, due mainly to the image automatically compressed to 36 KB and CloudFront still trying to transfer a 720 KB PNG.
Impressively, the hot cache was a staggering 3x faster: 0.133 vs 0.397 seconds.
What if we even the odds and make CloudFront and Cloudinary transfer the same file? Surely CloudFront should beat Cloudinary now? It’s not that simple. See the next section for Speed Test #2.
I re-ran the speed test to make sure CloudFront and Cloudinary were downloading the exact same file. To do this, I just uploaded the Cloudinary 36 KB file to CloudFront CDN.
Notes:
So….I found out Cloudinary doesn’t really have a cold cache? Even if I try running the test a few days after my last fetch…it is still pretty much the exact same as the hot cache result….
For example, I ran the Cloudinary test again, and I noticed the cold cache was only 0.02 seconds slower than the hot cache…nearly all of which was in the DNS lookup.
The coldest I’ve ever seen Cloudinary was when I waited a couple weeks to test Cloudinary. If you test only a few days after, it is pretty much the same as hot cache.
This is actually a good thing for the consumer. It means Cloudinary doesn’t degrade the file down to cold cache until a couple weeks. It is kind of incredible.
I’m not going to bother writing much of an analysis for this.
Cloudinary’s cold cache is pretty much as fast as the hot cache, with the only difference of the DNS lookup (was not cached by intermediate routers).
CloudFront’s cold cache is just the same as last time except for a significantly faster Data Transfer phase since we are making CloudFront download 36 KB.
Much closer where we can say that perhaps CloudFront is as fast as Cloudinary. Cloudinary holds a slight 12% faster time. Cloudinary still 12% faster than CloudFront. Although the absolute difference is only 0.016 seconds so perhaps not a big deal.
DNS lookup, TCP handshake, SSL handshake, Data Transfer were all pretty close (these are the same operations for any file size or type).
The main difference of 0.010 seconds comes from Request Latency, where CloudFront takes 50% long (0.030 vs 0.20 seconds). Honestly not sure but perhaps Cloudinary has a more efficient file cache read than CloudFront. Cloudinary is built on Fastly, which has significant market share among enterprise companies.
So Cloudinary is faster, but it’s not really worth stressing about it at this point. The difference is small enough.
Same thing that happened in Jetpack CDN vs AWS CloudFront. CloudFront warm cache degraded significantly (relative to hot cache) — 2x slower (0.25 seconds vs 0.126 seconds). Cloudinary warm cache pretty much the same as hot cache.
Regarding Request Latency*: the big rock was Request Latency: 0.076 vs 0.0168 seconds. Cloudinary’s Request Latency was the same in both hot and warm cache, so Cloudinary must be keeping the file in RAM. CloudFront definitely downgraded the file from RAM down to disk. This is very consistent behavior that I’ve seen in the* Jetpack CDN vs Cloudfront comparison as well.
(reminder: warm cache is download taken exactly 30 minutes after hot cache)
CloudFront’s speed performance is once again significantly slower as found when I was doing Jetpack CDN vs CloudFront. Cloudfront’s slowdown came in 3 areas: DNS lookup, SSL handshake, and Request Latency.
Regarding DNS lookup: Cloudfront is slower here because the DNS name d20zaq59cm4c4j.cloudfront.net is entirely unique to my account so it is even more unlikely to be cached in routers than the Cloudinary DNS name res.cloudinary.com (which appears to be shared with multiple users).
Interestingly, Cloudinary’s DNS lookup was significantly slower when going from the hot cache to the warm cache (0.035 seconds vs 0.0016 seconds).
Another interesting point is Jetpack CDN’s DNS lookup was only 0.0092 seconds. This happened because the Jetpack CDN DNS name i0.wp.com is heavily used across millions of wordpress installations and Cloudinary has significantly smaller install base, so the Jetpack’s DNS name is way more likely than Cloudinary to be cached in routers.
Regarding SSL handshake: it is really unusual that Cloudfront’s SSL handshake takes nearly 2x as long as Cloudinary (0.084 vs 0.045 seconds), because the TCP handshake occurred with equal speed on both CDNs, which indicates the problem is not the internet speed.
There are 2 possibilities: 1) for some reason the certificate authority is taking a long time to respond, and 2) the CloudFront is serving the traffic from a cheap CPU server so the SSL calculations are taking much longer?
I guess possibility #2 is more likely. Still weird.
My thoughts on this are extremely mixed. I would say it highly depends on your circumstances whether you should use Cloudinary.
Cloudinary is a highly performant CDN built on top of Fastly CDN, very widely used among tech companies such as Reddit and even Amazon itself (which is weird because Amazon has its own CDN called CloudFront…).
Cloudinary has some very impressive image compression capabilities. The 700 KB test image was compressed down to 36 KB. It’s possible to do the same thing in CloudFront…but it’s more involved. You’d need a WordPress plugin that was as good at compressing images. Actually, Jetpack CDN was already compressing, but only down to 216 KB. Again, really impressive stuff from Cloudinary. I guess nobody is compressing the image that well…(…yet. I will probably build this WordPress plugin).
Cloudinary keeps files in a hot cache state for weeks (much longer than CloudFront which degrades the file in less than 30 minutes).
Cloudinary also boasts video CDN delivery. I have not tested using videos so I can’t make an evaluation here. Although…it’s likely the video CDN performs as well as the image CDN, although we still need to test it.
Even in the scenario that CloudFront is delivery the same compressed file as Cloudinary, I’m seeing Cloudinary (i.e. Fastly) is performing better on cold, hot, and warm cache.
So…Cloudinary has been extremely impressive indeed.
However, the free tier is extremely limited to only 25 GB/month of data transfer, while the premium tier is very expensive (starting at $99/month). Cloudinary is by far the most expensive CDN I’ve tested so far. To put the $99/month in perspective: CloudFront only charges $0.08/GB, and Cloudinary has a free tier of 25 GB and premium tier of 225 GB. Run the numbers: 1) for the free tier, CloudFront would cost only 25 GB * $0.08/GB = $2.00. 2) for the premium tier, it’s 225 GB * 0.08/GB = $18. And…Cloudinary’s charging $99/month? Wow.
On the plus side, if you’ve got a low or medium traffic website and you’re sure you’re transferring less than 25 GB a month…by all means go for Cloudinary. Since you’re staying in the free tier.
Another limitation is you can’t host a static HTML page on Cloudinary like you can with CloudFront and CNAME Aliases. You can host static assets like CSS, JS, images, and videos…but not HTML. For example, this entire blog is hosted off CloudFront, even the initial HTML request. I can’t do that with Cloudinary…just offload the images/videos/CSS/JS, that’s it.
As an aside: there’s a good reason why Cloudinary is so expensive…it is built on top of Fastly CDN. Cloudinary’s primary value-add are image and video transformations. And Fastly is already fairly expensive (minimum $50/month).
In the final analysis, what you’re paying Cloudinary for are the “on-the-fly” image and video transformations. Cloudinary contains some bells and whistles that makes it a powerful image & video CDN. Is this worth $99/month to you? i.e. $1188/year.
Also remember Cloudinary is basically a reseller of the Fastly CDN. Cloudinary’s primary value-add is in the image and video transformations. Are you the kind of person or business that needs Cloudinary’s advanced features? It costs $99/month…
What kind of person or business are you?
Software engineer building complex app: Cloudinary has some complex image transformations like cartoonify, brightness, rotate. That’s neat. Using Cloudinary as a REST API could save you some time (and developer time is always the most expensive).
Python CDN Speed Test Script: I use this to automate the collection of metrics about CDNs.