Scaling

Do these apps scale?

Yes, for most of what people build. Your app runs on Cloudflare’s network with no server to size or restart, and Cloudflare adds capacity as traffic grows. The limit you’re likeliest to meet is the database: each D1 database holds up to 10 GB. When you outgrow that, the framework runs on Postgres too.

No servers to size

On a server, you pick a machine and hope it’s big enough. On Workers there’s no machine to pick. Your app runs in Cloudflare’s data centres close to whoever’s using it, and a quiet app costs nothing while it waits.

Most requests use very little computing time. Cloudflare’s own figure for an average Worker is about 2.2 milliseconds each, and time spent waiting on the database doesn’t count.

What it costs as you grow

The free plan covers 100,000 requests a day, reset at midnight UTC. Your app’s pages and form posts count; its images, scripts and styles are served free.

The paid plan is $5 a month and includes 10 million requests, then $0.30 for each million more. In Cloudflare’s own worked example, an app serving 15 million requests a month costs about $8.

What a web app on Cloudflare Workers costs works out the bill at each step, from 10,000 requests a month to 100 million.

The limits, in numbers

Cloudflare publishes every limit. These are the ones an app meets first, on the free plan and the $5 one:

  • Requests: 100,000 a day on the free plan, reset at midnight UTC. The paid plan has no daily limit, and neither plan has a general limit on requests a second.
  • Computing time: 10 ms of CPU time for each request on the free plan, and up to 5 minutes on the paid one, 30 seconds unless you raise it. Waiting on the database doesn’t count.
  • Memory: 128 MB for each copy of your app, and each copy serves many requests at once.
  • Database size: 500 MB for each D1 database on the free plan and 10 GB on the paid one, with 5 GB and 1 TB in all across your account.
  • Database work: on the free plan, 5 million rows read and 100,000 written a day, and up to 50 queries for each request. The paid plan includes 25 billion rows read and 50 million written a month, and allows 1,000 queries for each request.

Pages served from the edge

A page that reads nothing about the visitor, such as a landing page, is kept in Cloudflare’s cache by default, so it’s served without asking the database or rendering it again.

Pages that show stored data, such as a blog post, can be cached for a time too, and cleared the moment that data changes. Data that takes work to compute can be cached the same way, and cleared by the same changes.

The database

D1 is built on SQLite. Each database holds up to 10 GB on the paid plan and 500 MB on the free one, which is a great deal of text: most internal tools never come close.

A single D1 database works through queries one at a time. By Cloudflare’s own reckoning, if each takes a millisecond, that’s about 1,000 a second. Writes that must happen together go in one batch, so they all land or none do.

If you outgrow it, the framework also runs on Postgres through Cloudflare Hyperdrive. Your pages and most of your actions stay as they are.

The cost guide moves the data to Postgres at 50 million requests a month. If each page runs five queries and the busiest hour is three times the average, that’s nearly 300 queries a second for one database. Move sooner if your data is heading for 10 GB.

What breaks first in a vibe-coded app

An app that works for ten people can struggle at ten thousand for reasons no bigger server would fix. Here are four, and what the framework does about each:

  • Data kept in the app’s memory. On Workers, one copy of your app serves many visitors at once, so a value kept between requests can reach the wrong person. A lint rule reports it, and says what to use instead.
  • Lists that load every row. A page that reads a whole table slows as the table grows. The framework’s docs page through a list by the last row shown, so each page reads only what it shows.
  • Two people saving at once. A rule such as stock that can’t go below zero goes in the database, so it holds however many requests arrive together.
  • Queries with no index. A D1 database works through one query at a time, so a slow one holds up the rest. Cloudflare’s advice is to index the columns your queries filter on.

Slow work, off the page

Work that doesn’t need to finish before the page loads, such as sending an email or resizing a photo, runs after the response. Queues work through bigger jobs, and scheduled jobs run at the times you set. None of it needs a server kept running.

When to think about it

For most apps, not for a long while. These are the signs it’s time:

  • You’re near 100,000 requests a day: move to the $5 plan, and nothing in your app changes.
  • Your database is heading for 10 GB: split it, or move to Postgres.
  • Pages that show everyone the same thing are slow: check they’re cached.
  • A page does heavy work every time: move that work to the background.

Questions people ask

Do vibe-coded apps scale?

They can. Who wrote the code matters less than what it runs on and a few habits. On @popcomputer/web there’s no server to outgrow, the lint rules report data kept in memory, and the first limits you’ll meet, the database’s size and speed, are published and far off for most internal tools.

How many people can use it?

It depends on how many pages each person opens. If each opens 50 a day, the free plan’s 100,000 requests covers about 2,000 people a day, and the $5 plan far more.

What happens if I go over the free plan?

Cloudflare answers your app’s requests with an error page, error 1027, until the count resets at midnight UTC. Its limits page has the details. Moving to the paid plan lifts the daily limit.

Do I have to change my code to scale?

Not for more traffic. Moving from D1 to Postgres changes the database setup and its migrations, while your pages and most of your actions stay the same.