Save bandwidth on Vercel with Cloudflare
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.
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).
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!
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%
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:
- https://developers.cloudflare.com/fundamentals/get-started/setup
- https://developers.cloudflare.com/fundamentals/get-started/setup/add-site
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:
- Select your site from https://dash.cloudflare.com
- Select Caching → Cache Rules → Create rule
- 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! 🎊
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:
- https://www.youtube.com/watch?v=d_OnTmRSohg - My talk about browser extensions and Clippy at Halfstack London 2022 📽
- https://get.komfy.app - Stream your favorite video content from your phone directly to your PC or Mac 📺
- https://medium.com/@capJavert/doing-100-000-push-ups-this-year-with-the-help-of-siri-605c3c8eb18f - How I did 100,000 push-ups in a year 💪
- https://jawa.kickass.codes - Visual scraper interface, exports to puppeteer script which you can run anywhere and scrape anything 🤖