← Back

My Thoughts on the Cloudflare Stack

My Experience and whether I'll use it going forward

10 min read

Web apps and hosting

When it comes to web development, I’m often a victim of analysis paralysis. It’s easy to be overwhelmed with all of the different web technologies that are out there. For example - frontend and backend frameworks, ORMs, cloud providers, styling solutions, authentication methods, etc. Over the past few years of working as a web dev, fortunately I’ve managed to narrow down a set of technologies that usually works for me. React Router 7 + ShadCN have been my go-to on the frontend, and I tend to employ NestJS and PostgreSQL on the backend.

However, I’m still a bit undecided when it comes to hosting. I’ve normally used some mixture of AWS, Vercel, and Digital Ocean, but I’ve found all of these lacking in different ways. One of the chief issues I’ve had to consider is pricing. This is my technology choice for personal projects, and oftentimes I’m developing small apps that will probably have no users, or at the most, me and a few other people. Paying 10 bucks a month for a server, and another 15 bucks for a database isn’t the most enticing option.

While researching solutions for hosting apps cheaply, I came across Cloudflare. Cloudflare workers, the core technology they use to host web apps, is serverless. This means I would only be charged for when the app is actually used, and not when there’s downtime with zero users. For a small app, I would pay almost nothing.

I decided to host some simple projects of mine on Cloudflare. Here’s an overview of Cloudflare’s services, their pros and cons, and whether I’ll use it going forward.

Cloudflare’s Strengths

To me, Cloudflare’s primary selling point is that they have pretty much every service required to host web apps, at reasonable prices in a pay-as-you-go model. I’ve listed some of the main services they offer below:

Cloudflare pages and workers

This is Cloudflare’s product for hosting web applications. At a high level, pages are for hosting static sites, whereas workers provide a serverless runtime for full stack applications and code execution, deployed on Cloudflare’s global network. It’s a little more nuanced than that, since Cloudflare pages can call page functions, and Cloudflare workers can be configured to just use static assets, but that’s the paradigm I’ve been working with in my own projects.

Cloudflare workers and pages serve static assets completely free, which makes Cloudflare an excellent option for static sites like blogs or portfolios.

Workers have several advantages over other full stack hosting solutions, which boils down to their use of V8 isolates. A request for your web app goes to one of Cloudflare’s machines on their network, which has an instance of the workers runtime. This runtime uses the V8 engine under the hood, the same engine powering Node.js and Chrome. The Cloudflare server runs the user defined workers code in V8 isolates, which are essentially sandboxes that keep the code protected and prevent it from accessing other variables/user code not belonging to it.

These V8 isolates are much faster than other serverless solutions. A long running Workers runtime can just execute your code, skipping the steps of setting up a vm and starting the Node.js runtime.

Cloudflare workers also bill per CPU time, with a generous free tier. This means that you aren’t paying for a running server when no one is using your app, making it ideal for personal projects with few users.

Cloudflare D1 + KV

D1 is Cloudflare’s serverless SQLite database. Like with Workers, D1 billing is measured per usage - specifically, rows read, rows written, and data stored. However, you need to reach over 5 million reads a day, and/or over 5GB data stored to exceed the free tier, so for small personal projects it’s essentially free. You get a scalable database solution with features like logging and backups, without having to pay 15 bucks a month for a managed Postgres server from a platform like Digital Ocean or AWS.

Workers KV is another data storage solution, but designed for a high amount of reads with low latency. This can be used by workers to cache expensive API calls or store user auth details, and avoid a longer call to the D1 database. Unlike a solution such as Redis, however, Workers KV is global. Writes to a KV are also written to a central data store, which will be eventually propagated to local Workers KV caches located around the world.

Cloudflare R2 + Images

R2 is the object storage service of Cloudflare, their equivalent of S3, and can be used to store files, images, videos, etc. A big advantage is they have zero egress fees, meaning the only payment is for writes and storage, and they have an S3 compatible API.

For a more complete, out of the box solution, there’s Cloudflare Images. With this, you can dynamically resize, optimize, and manipulate images through Cloudflare’s API, meaning you don’t have to handle the whole process yourself. For example, instead of storing multiple versions of the same image at different sizes (a thumbnail and full sized version), you can simply set the size in the url parameters and let Cloudflare take care of the rest.

Cloudflare Durable Objects

Durable Objects can be used for building distributed systems that require coordination across multiple clients. They combine Cloudflare workers with state. I personally am not too familiar with this service, but there is an excellent YouTube video that goes through some of the use cases.

What this looks like in practice

Let’s say you have a social media platform. The actual web app itself, made with SvelteKit, can be hosted on Cloudflare workers, and the static marketing site can be hosted on pages. Certain API calls can be cached with Workers KV, and we can use D1 for the central database. Backups can be stored in R2, and user profile images and uploaded media can be stored in Cloudflare Images. Durable Objects can handle live messaging between users. Domain names, SSL/TLS, bot mitigation, etc. can also be handled with Cloudflare. In short, it has pretty much everything you need to get a site up and running, and most of its services can be used very cheaply, or for free if you’re under a certain usage threshold.

Why not another option?

Of course, Cloudflare is far from the only hosting platform in the game. In the past, I have used AWS, Digital Ocean, Vercel, etc. In general, I think Cloudflare is actually a much better option for hosting personal projects.

Firstly, let’s consider what most hobbyists are likely starting with - Vercel. Vercel is quite a convenient solution if you’re hosting a Next.js app, which shouldn’t be surprising considering they are the ones behind the framework itself.

Since Vercel is a serverless platform, it’s possible for bots or malicious actors to send a massive amount of requests to your app. Vercel will auto scale and will keep responding to these requests, running up a huge bill. This is not an uncommon occurrence, and there’s countless stories of this online. Even disregarding malicious actors or loops caused by user error, Vercel is quite expensive! It’s built on top of AWS, meaning that you are always going to end up paying a bit more for convenience.

On top of that I don’t use Next.js (I’m a React Router fan), so a lot of the built in benefits of Vercel don’t carry over to my own work. Vercel also lacks built in database and auth providers.

Digital Ocean and AWS are other platforms I’ve used in the past, but they aren’t my preferred choice for hosting apps. Digital Ocean doesn’t have a convenient image hosting solution, and their method of hosting static web apps (app platform) costs extra. They also don’t have a way to buy a domain name.

AWS is more complete, and I use it at my job everyday. However, it’s complex and very much overkill if you just want to get a hobby project up and running ASAP.

Compared to these other solutions, Cloudflare offers everything I need at cheap rates, and has a convenient DX for deployment with their Wrangler CLI. So it should be the default option, correct?

Why I’m hesitant

Despite Cloudflare’s wealth of features at a reasonable price, I’m still unsure to what degree I’m going to use it in the future. Ironically, my key concern is also one of its major selling points - the serverless, pay-for-what-you-use model.

As I mentioned with Vercel, this solution is ideal for small personal projects, and for projects where you don’t want to worry about the infrastructure, but it allows a malicious actor to jack up your costs by sending massive amounts of requests to your site, in what’s sometimes called a “denial of wallet attack”. Cloudflare’s R2 and Durable Objects seem particularly susceptible to this.

There are fortunately robust ways to protect against this.

Firstly, Cloudflare offers WAF rate limiting. This lets you limit the number of API calls a single client can make within a certain time period, preventing them from reaching your worker and burning CPU time. Rules can be set by IP, endpoint, or session, depending on the specificity you need. Cloudflare also offers Turnstile, which can be put in front of endpoints to force the user to solve a CAPTCHA-like challenge.

Despite these solutions, there is no official method for providing a hard cap on the amount you spend with Cloudflare, although this is true with any Pay-as-you-go hosting service.

There are some non-official solutions, however. PizzaConsole details a project for building a Cloudflare workers usage monitor with a kill switch. His app has a separate CF worker running every five minutes to fetch billing info from the Cloudflare GraphQL API, and disconnects workers and alerts if the usage exceeds a certain amount.

Another potential issue I have with Cloudflare is how much of their technology is tied to their platform. If you build an app with Workers, Images, KV, D1, etc. - how easily can that be transferred to another cloud provider? I’m not sure, since I’m still getting acquainted with Cloudflare, but it seems like it would be quite a hassle compared to hosting on your own VPS.

Finally, they don’t have a great database service. D1 is distributed SQLite. There’s nothing wrong with SQLite and it works great for small projects, but it doesn’t allow for concurrent writes (only 1 writer at a time). For large scale web applications with many users, this would be a severe limitation.

Conclusion

Cloudflare offers some essential and reasonably priced features that I will probably keep using. Namely, Images, Pages, and the Domain name/SSL services.

However, when it comes to hosting full stack applications themselves, or databases, I’m still on the fence. I think ideally, I would use a service such as AWS or Digital Ocean, but the expense is a deterrent. Hosting a small Digital Ocean droplet, caching, managed database, etc. could easily cost upwards of $20 a month, which makes it non viable for personal projects.

For this reason, I’ve decided I will try out a cheap VPS service. OVH, for instance, offers a VPS with 8 GB RAM and 4 vCores for only ~7 dollars a month. That alone would be enough to host all of my current personal projects. I don’t need to worry much about scalability, since the userbase will probably be minuscule.

The VPS route will give me extra experience on the devops + infrastructure side as well, and I’m eager to dive into some solutions I have been reading about online.

This was sort of a long article, but I look forward to trying out this new approach on future projects.