Let's get straight to the point. Vercel's CDN costs are crazy high. Here is a snapshot of their "Fast Data Transfer" cost which is essentially just a regular CDN.
Let's compare the cost of this to CloudFront - a world-class CDN.
You can see that Vercel's cost of $0.3 per GB is almost 3x of what CloudFront charges. This article focuses on how to reduce the data transfer on Vercel as well as how to divert big traffic away to cheaper CDN.
High Data Transfer?
If you are seeing high data transfer bills on Vercel, chances are that you are having a lot of images on your web application. Text data can be compressed very well and it's very unlikely to cross that 1TB FREE tier of Vercel just with text data.
Once you take a closer look, you will realise that it's images which are consuming that data. One quick option you have in Vercel is to use their image optimization service. It resizes images so output bandwidth is reduced. However, it comes with its own cost. 🙁
Move Images Away
The only and best solution is to move that image data transfer away from Vercel. The basic and simplest thing to do is to start using CDN like CloudFront to deliver images and reduce the cost by 3x!
There is even a better way to handle this. Gumlet provides an image optimization service for which there is no extra charge like "Master Image Pricing" and the only price you pay is going to be the optimized bandwidth price. The cherry on top? Gumlet uses the same CloudFront as CDN to deliver images.
Gumlet's pricing is even cheaper than CloudFront at just $0.08 per GB. This means you not only reduce GBs because of optimized images but also save 20% more compared to just barebone CloudFront.
Integrating Gumlet
Gumlet is extremely easy to integrate with Next.js. All you have to do is create an image source on Gumlet and provide your image base path as input for that source. For example, if your Next.js application is hosted on www.example.com, add https://www.example.com as the base URL in the source setup.
Once the source is created, you need to edit next.config.js
like this:
/** @type {import('next').NextConfig} */
const nextConfig = {
distDir: 'build',
images: {
loader: 'custom',
loaderFile: './utils/imageloader.js',
},
//... other config
}
module.exports = nextConfig
You also need to create a new file in ./utils/imageloader.js
export default function gumletLoader({ src, width, quality }) {
if(src.includes("<CURRENT_IMAGE_DOMAIN>")){
let parsedUrl = new URL(src);
parsedUrl.hostname = "<GUMLET_SUBDOMAIN>.gumlet.io";
parsedUrl.searchParams.set("w", width);
parsedUrl.searchParams.set("q", quality || 80);
return parsedUrl.toString();
} else {
return `${src}?w=${width}&q=${quality || 80}`;
}
}
Just replace <CURRENT_IMAGE_DOMAIN>
and <GUMLET_SUBDOMAIN>
in the above code and you are done. Now, all images in your application will be delivered via Gumlet in the correct size, format and quality.
This ends up reducing data transfer on Vercel and gives you a way better price per GB for your image data transfer.
I hope this helps you save those precious dollars 😄