Welcome back to this series all about file uploads for the web. In the previous posts, we covered things we had to do to upload files on the front end, things we had to do on the back end, and optimizing costs by moving file uploads to object storage.
- Upload files with HTML
- Receive uploads in Node.js (Nuxt.js)
- Optimize storage costs with Object Storage
- Optimize performance with a CDN
- Secure uploads with malware scans
Today, we’ll do more architectural work, but this time it’ll be focused on optimizing performance.
Recap of Object Storage Solution
By now, we should have an application that stores uploaded files somewhere in the world. In my case, it’s an Object Storage bucket from Akamai cloud computing services, and it lives in the
So when I upload a cute photo of Nugget making a big ol’ yawn, I can access it at austins-bucket.us-southeast-1.linodeobjects.com/files/nugget.jpg.
Nugget is a super cute dog. Naturally, a lot of people are going to want to see this. Unfortunately, this photo is hosted in the
us-southeast-1 region, so anyone living far away from that region has to wait longer before their eyes can feast on this beast.
And that’s why CDNs exist.
What Is a CDN?
CDN stands for “content delivery network“, and it’s a connected network of computers that are globally distributed and can store copies of the same files so that when a user makes a request for a specific file, it can be served from the nearest computer to the user. By using a CDN, the distance a request must travel is reduced, thereby resolving requests faster, regardless of a user’s location.
Here’s a WebPageTest result for that photo of Nugget. The request was made from their servers in Japan, and it took 1.1 seconds for the request to complete.
Instead of serving the file directly from my Object Storage bucket, I can set up a CDN in front of my application to cache the photo all over the world.
So users in Tokyo will get the same photo but served from their nearest CDN location (which is probably in Tokyo), and users in Toronto are going to get that same file but served from their nearest CDN location (which is probably in Toronto).
This can have significant performance implications.
Let’s look at that same request, but served behind a CDN. The new WebPageTest results still show the same photo of Nugget, and the request still originated from Tokyo, but this time it only took 0.2 seconds; a fraction of the time!
When the request is made for this image, the CDN can check if it already has a cached version. If it does, it can respond immediately. If it doesn’t, it can go fetch the original file from Object Storage, then save a cached version for any future requests.
Note: the numbers reported above are from a single test. They may vary depending on network conditions.
The Compounding Returns of CDNs
The example above focused on improving the delivery speeds of uploaded files. In that context, I was only dealing with a single image that is uploaded to an Object Storage bucket. It shows almost a full-second improvement in response times, which is great, but things get even better when you consider other types of assets.
When a webpage loads, as the browser comes across a render-blocking resource, it will pause parsing and go download the resource before it continues (hence “render-blocking”). So any latency that affects a single asset may also impact the performance of other assets further down the network cascade.
This means the performance improvements from a CDN are compounding. Nice!
So is this about showing cute photos of my dog to more people even faster, or is it about helping you make your applications run faster? YES!
Whatever motivates you to build faster websites, including a CDN as part of your application infrastructure is a crucial step if you plan on serving customers from more than one region.
Connect Akamai CDN to Object Storage
I want to share how I set up Akamai with Object Storage because I didn’t find much information on the subject, and I’d like to help anyone that’s looking for a solution. If it doesn’t apply to your use case, feel free to skip this section.
Akamai is the largest CDN provider in the world, with something like 300,000 servers across 4,000 locations. It’s used by some of the largest companies in the world, but most enterprise clients don’t like sharing which tools they use, so it’s hard to find Akamai-related content.
(Note: You will need an Akamai account and access to your DNS editor.)
In the Akamai Control Center, I created a new property using the Ion Standard product, which is great for general-purpose CDN delivery.
After clicking Create Property, you’ll be prompted to choose whether to use the setup wizard to guide you through creating the property, or you can go straight to the Property Manager settings for the new property. I chose the latter.
In the Property Manager, I had to add a new hostname in the Property Hostnames section. I added the hostname for my application. This is the URL where users will find your application. In my case, it was “uploader.austingil.com”.
Part of this process also requires setting up an SSL certificate for the hostname. I left the default value selected for Enhanced TLS.
With all that set up, Akamai will show me the following Property Hostname and Edge Hostname. We’ll come back to these later when it’s time to make DNS changes.
- Property Hostname: uploader.austingil.com
- Edge Hostname: uploader.austingil.com-v2.edgekey.net
Next, I had to set up the actual property’s behavior, which meant editing the Default Rule under the Property Configuration Settings. Specifically, I had to point the Origin Server Hostname to the domain where my origin server will live.
In my DNS, I created a new A record pointing origin-uploader.austingil.com to my origin server’s IP address, then added a CNAME record that points uploader.austingil.com to the Edge Hostname provided by Akamai.
- A: origin-uploader.austingil.com -> origin server IP
- CNAME: uploader.austingil.com -> uploader.austingil.com-v2.edgekey.net
This lets me build out my CDN configuration and test it as needed, only sending traffic through the CDN when I’m ready.
Finally, to serve files in my Object Storage instance through Akamai, I created a new rule based on the blank rule template. I set the rule criteria to apply to all requests going to the
The rule behavior is set up to rewrite the request’s Origin Server Hostname and change it to my Object Storage location: npm.us-southeast-1.linodeobjects.com.
This way, any request that goes to uploader.austingil.com/files/nugget.jpeg is served through the CDN, but the file originates from the Object Storage location. And when you load the application, all the static assets generated by Nuxt are served from the CDN as well. All other requests are passed through Akamai and forwarded to origin-uploader.austingil.com, which points to the origin server.
So that’s how I’ve configured Akamai CDN to sit in front of my application. Hopefully, it all made sense, but if you have questions, feel free to ask me.
To Sum Up
Today we looked at what a CDN is, the role it plays in reducing network latency, and how to set up Akamai CDN with Object Storage.
But this is just the tip of the iceberg. There’s a whole world of tweaking CDN configuration to get even more performance. There are also a lot of other performance and security features a CDN can offer beyond just static file caching: web application firewalls, faster network path resolution, DDoS protection, bot mitigation, edge compute, automated image and video optimization, malware scanning, request security headers, and more. My colleague, Mike Elissen, also covers some great security topics on his blog.
The most important thing that I wanted to convey today is that using a CDN improves file delivery performance by caching content close to the user.
I hope you’re enjoying the series so far and plan on sticking around until the end. We’ll continue next time by looking at ways to protect our servers from malicious file uploads.
Thank you so much for reading. If you liked this article, and want to support me, the best ways to do so are to share it and follow me on Twitter.