Save bandwidth on Vercel with Cloudflare

Ante Barić
6 min readFeb 6, 2023

--

Let’s save some bandwidth!

Vercel free tier is a great way to deploy projects of low to middle scale almost without any costs. Usage limits are generous but when deploying projects with more requests/sec or lots of media content (eg. images/videos) the first usage limit you will likely cross is 100 GB of bandwidth. If you want to know how to save some bandwidth and stay on the free tier for most of your projects, read on…

So few years back I created Clippy browser extension. It is a goofy feel good extension that brings back old MS Word assistant Clippy back to your browser to help (annoy) you with his tips & tricks.

Screenshot showing Clippy inside of the browser. He is on the Google website and saying “Maybe try Bing?”
Clippy inside of your browser!

So what does Clippy has to do with hosting and bandwidth? Well, in my browser extension all the things that Clippy can say are located inside of word dictionary hosted on GitHub. Anyone can contribute with additional phrases for different websites through PRs and after merge the new phrases will be automatically pulled into all of the extensions and Clippy will be able to say even more. Throughout the years extension amassed thousands of users across Chrome, Firefox and Opera extension stores so number of requests to my dictionary endpoint grew quite a lot.

The setup

This is how I used to host and manage Clippy dictionary.

  • Content is hosted on GitHub and it changes any time someone opens a PR and I merge it after review #checkcode
  • When content changes it is automatically built (JSON is parsed and minified)
  • After build the dictionary contents are automatically deployed on Vercel as single static file
  • It is made available on https://clippy-dictionary.kickass.website
  • Browser extension instances automatically fetch dictionary contents when user opens a new tab
  • This then hits my dictionary endpoint and costs me bandwidth

The problem

So with thousands of users you can see how this ramps up pretty quickly, for example in November (2022) my Clippy endpoint amassed 10GB of bandwidth (which is 10% of 100GB allowed bandwidth in Vercel free tier).

Chart showing bandwidth usage for dictionary in November 2022, usage is 10GB.
Bandwidth usage for dictionary in November 2022

Also this accounted for 84.9% of bandwidth across all of my 30+ other projects that I host on Vercel. It was just wild to see that!

Chart showing bandwidth usage across all of my projects. Usage for dictionary is 84.9%
Bandwidth usage across all of my projects in November 2022

One thing that I immediately did after I have seen this was to check cache hit ratio for my deployment. This was because for most of the time dictionary does not change so I should have a very good cache hit ratio.

After checking my usage dashboard on Vercel I was right! Even better my cache hit ratio was 97.3%

Chart showing cache hit/miss ratio for dictionary in November 2022. Ratio is 97.3%
Cache hit/miss ratio for dictionary in November 2022

This of course was expected as I was hosting my dictionary as static JSON file which is automatically cached by Vercel Edge Network. The real problem is that Vercel bills you for all bandwidth (cached or uncached). From the their docs:

As a Vercel customer, you will be billed for both Cached and Uncached requests.

I wrongly assumed that cached requests would be free, my logic was, if there is no compute there is no costs. But again Vercel is serving millions of customers every day so I can not blame them for this, they have a great service overall 👏 … but still It was crazy that hosting a single file would occur this much bandwidth. I needed to do something about that.

The solution

Fortunately there is another provider that also offers a generous free tier but their main service is content delivery and bandwidth. Of course I am talking about Cloudflare.

Cloudflare does not have a bandwidth limit on their free tier. Which is wild because they are probably serving even more users then Vercel, but as a company whose core business is content delivery I guess it makes sense.

As I was already using Cloudflare to manage all of my domains DNS records the solution for me was as simple as to enable proxy in front of my Vercel deployments. If you are using other DNS providers you can check with them if they support DNS proxy and caching. If your current provider does not have these capabilities or you are using Vercel as your domain DNS provider you can switch to Cloudflare at no costs pretty easily. Check the following links for more info:

The above mostly involves changing nameservers of your domain to Cloudflare nameservers.

When you have your domain up and running with Cloudflare you can now customize caching behaviour for different paths of your website.

This is how I added caching rule for my dictionary endpoint:

  1. Select your site from https://dash.cloudflare.com
  2. Select Caching → Cache Rules → Create rule
  3. Set the name for your Rule and matching expression:

As I serve my dictionary on a subdomain I selected Hostname match and put in my subdomain. What that means is that any requests coming to my subdomain will now firstly go through Cloudflare and if cache is a hit it will be served from Cloudflare’s Edge network without ever touching Vercel servers (thus saving bandwidth).

You can also choose different matching fields eg. Path:

You can also use different operators as contains or starts-with or even regex (regex is available only in paid tiers).

4. The last thing is to set a cache TTL for deployment

I have set my TTL to 1 day because I get PRs for dictionary changes every other week or so. Even if I got new PR every day this would be more then enough.

Also make sure you set Edge TTL as this is the one that is server side controlled and will protect your origin server/app, Browser TTL only controls browser/network proxy caching and is suitable to invalidation if user requests your page with Cache-Control: no-cache header.

I deployed my caching rule on Cloudflare and after few weeks I went back and checked bandwidth usage inside of my Vercel dashboard. It was a clear win! 🎊

Chart showing Bandwidth usage for dictionary after adding Cloudflare proxy and caching. Usage is now only 6.23 megabytes.
Bandwidth usage for dictionary after adding Cloudflare proxy and caching

In the month of January (2023) my bandwidth usage for dictionary was only 6.23MB. Which is wild when just a month before it was 1600 times larger at ~10GB.

With all of that bandwidth saved we will be able to host many more projects with this Vercel + Cloudflare combination for years to come ✅

If you are interested in Clippy or some of my other side project check below:

--

--

Ante Barić

I am experienced software developer, probably not that much freaky movie freak and passionate runner hailing from Croatia.