How I Run a Multi-Tenant SaaS on Cloudflare Workers for $5 a Month

A look at the actual costs and operational overhead of running a multi-tenant SaaS on Cloudflare Workers and D1, based on production use with real tenants and real traffic.

How I Run a Multi-Tenant SaaS on Cloudflare Workers for $5 a Month

The first question I get when I say my entire backend runs on Cloudflare Workers is: “But doesn’t that get expensive?”

No. The Workers paid plan is $5 a month for up to 10 million requests. I am nowhere near that threshold. For a small SaaS with a few tenants and bursty traffic, this math is hard to argue with.

What I’m Running

The app is Pillar Press, a multi-tenant content generation platform I built for xops360. It has an external client tenant on the free tier and an internal tenant I use for my own blog. The single Worker handles auth (magic link via Resend, Shopify OAuth), AI content generation calling Anthropic’s API, a draft review queue, and GitHub API commits for blog publishing.

The database is D1, Cloudflare’s managed SQLite. The schema has 13 tables across 8 migrations. Reads from the Worker are under 5 milliseconds in production logs because the Worker and D1 run in the same edge location. No connection pool to manage, no RDS instance to babysit.

What Surprised Me

Cold starts are not a thing. This was my biggest concern before committing to Workers. Lambda and Cloud Run have noticeable cold start time if the function has not fired in a few minutes. Workers use the V8 isolate model, so the runtime is already warm. Your startup time is only your own initialization code.

The local development story is also better than I expected. Running wrangler dev --remote proxies real D1 queries and R2 operations to the actual cloud instance. My local Worker hits the same database as staging. That killed an entire class of “works locally, breaks in prod” bugs I had with every other serverless platform.

The Catch

Workers CPU limits only count actual compute time, not time spent waiting for external API responses. A Claude Sonnet call that takes 10 seconds wall-clock consumes a few milliseconds of CPU. The 30-second CPU limit is not the issue.

The real constraint is that a Worker stays open for the full duration of the request. If an AI call takes 12 seconds, that connection hangs open for 12 seconds. For a generation pipeline that chains two AI calls back to back, you are looking at 20 or more seconds of open connection time, which creates reliability and UX problems.

My fix was to break the pipeline into separate requests. Generate fires one Worker invocation. Revision fires another. Draft state stored in D1 connects them. This forced better architecture: each step is independently retryable and the UI can show real progress between steps.

There are no long-running background jobs either. Workers do not replace a process that runs for 10 minutes. For anything batch-heavy, I reach for a separate service. But for a request-driven SaaS, that is rarely the constraint.

Should You Switch?

If your app is request-driven and you want to minimize infrastructure overhead, yes. The operational cost is close to nothing. I have not thought about uptime, patching, or capacity planning in 8 months of running production tenants on this stack.

If you have batch jobs that run for minutes or need a full POSIX file system, Workers will not replace those pieces. But for the API layer of a small SaaS, the cost and complexity reduction is real.

Frequently Asked Questions
Does Cloudflare Workers support databases?

Yes. D1 is Cloudflare's managed SQLite database, designed specifically for Workers. It runs in the same Cloudflare data center as your Worker, so reads are typically under 5 milliseconds. The free tier includes 5 GB of storage and 5 million rows read per day. For most small-to-medium SaaS applications, D1 is sufficient without an external database.

What is the CPU time limit on Cloudflare Workers?

On the Workers paid plan ($5 per month), the limit is 30 seconds of CPU time per invocation. On the free tier, it is 10 milliseconds, which you will hit immediately with any real work. For AI workloads, time spent waiting for an external API response does not count against your CPU time budget.

Discussion

Adam Bishop

Veteran, entrepreneur, and independent researcher. Writing about formal methods, AI governance, production systems, and the operational discipline that connects them. Every project here demonstrates hard thinking on simple infrastructure.