Groundbase
← Back to the Pipeline
Notes

Why I built Groundbase on Cloudflare Workers instead of Vercel

Groundbase's backend runs on Cloudflare Workers, with a database for each account. This website runs on Vercel. Here's what the Workers choice means if you use Groundbase — speed, things that run while the app is closed, no egress bills — what it costs, and where it's the wrong tool.

Groundbase's backend runs on Cloudflare Workers, with Turso for the data. The website you're reading is a Next.js site on Vercel. Both of those are deliberate, and they answer different questions.

I picked Workers for the part customers depend on: the API every app talks to, the jobs that run on a clock, and the server your AI assistant connects to. This post is what that choice means if you use Groundbase, what it costs me, and where it's the wrong tool. Prices and limits checked October 2026 on Cloudflare's and Vercel's own pages.

What runs where

Before the reasons, the parts list, because "built on Workers" can mean a lot of things.

  • The API at api.groundbasecrm.com is a Worker. The web, Windows and Android apps all talk to it.
  • Campaigns run in a second Worker on a cron every minute: scheduled sends, drips, daily limits and sending windows.
  • The MCP server, the thing Claude, ChatGPT or Cursor connects to, is a third Worker. What MCP is, if the term is new.
  • Cron Triggers run the API's clock every minute: scheduled texts, workflow waits that are due, outbound webhook deliveries.
  • Queues carry workflow runs, so each run is its own job with its own time budget rather than riding on the request that triggered it.
  • KV holds rate limits.
  • R2 stores images in campaign emails, the PDFs you send for signature, and the Windows and Android installers.
  • Turso (libSQL, a fork of SQLite) holds the data, hosted in Ohio on AWS us-east-2.
  • The web app at app.groundbasecrm.com is a static build on Cloudflare Pages.
  • This website is Next.js on Vercel.

No ORM and no backend framework: TypeScript on the Workers runtime, plus Stripe, Twilio and Resend through your own accounts.

What it means if you use Groundbase

The API is quick to answer, from the first click

Cloudflare's network page lists 348 cities. Workers run as isolates inside an already-running runtime rather than a container per function, and Cloudflare's own explanation says that model "eliminates the cold starts of the virtual machine model". In practice: the first click of the morning isn't the slow one.

To be accurate about the other half: your data lives in one place, Ohio, and the Worker talks to it from wherever it's running. I once wrote that Turso put your data "at the edge" next to the compute. That isn't how Groundbase runs, and I'd rather correct it than leave it. For a CRM sold to one-person businesses in Canada and the US, Ohio is a short trip.

Things happen while the app is closed

A CRM for one person has to work while that person is with a client. Scheduled texts, workflow waits, campaign drips, booking reminders and webhook deliveries all run on Cloudflare's crons and queues, not in your browser. Close the laptop and the 9am text still goes at 9am.

When a webhook you've pointed somewhere fails, it's retried after 1 minute, 5 minutes, 30 minutes, 2 hours and 12 hours. Workflow runs travel on a queue, so a slow step in one doesn't hold up another.

Your data is in its own database

SQLite databases are cheap enough to make one per account, so each new Groundbase account gets its own database when it's set up. Your contacts aren't rows in a shared table next to everyone else's, kept apart by a WHERE clause I have to remember to write on every query.

It has a cost, and I've paid it: a change to the shape of the data has to reach every database, including ones created after the change. But the isolation is worth it, and it makes leaving Groundbase simpler too: your account is one database, and the export is all of it.

Downloads and images don't run up a bill

R2's pricing page says egress "does not incur data transfer (egress) charges and is free". Storage is $0.015 per GB-month. The Windows installer is over 130 MB, and every image in a campaign email is fetched by every recipient who opens it. On storage that charges per gigabyte out, both of those grow with every customer. On R2 they don't.

Call recordings are the exception, and on purpose: they stay in your own Twilio account.

One person can run it

There are three main Workers, one database product, and a handful of Cloudflare primitives. That's small enough for one person to hold in their head, deploy, and fix on a Sunday. For a solo founder, that matters more than any benchmark. Groundbase has no on-call rotation. It has me.

The bill

Cloudflare Workers, from the pricing page:

  • Free: 100,000 requests a day.
  • Paid: a $5 a month minimum, with 10 million requests and 30 million CPU milliseconds included, then $0.30 per additional million requests and $0.02 per additional million CPU milliseconds. "There are no additional charges for data transfer (egress) or throughput (bandwidth)."
  • Queues on the paid plan: 1 million operations a month included, then $0.40 a million.

Vercel, from its pricing page:

  • Hobby is $0 and, in Vercel's words, "for personal, non-commercial use".
  • Pro is $20 a month per developer seat, with a $20 usage credit and 1 TB of Fast Data Transfer included, "then starting at $0.15 per GB".

At Groundbase's size, either would be a small line item. The argument isn't that Vercel is expensive. It's the shape of the bill as it grows. Workers charges for requests and CPU time and not for bandwidth, so I can work out what another hundred customers cost before they arrive.

That's part of why Groundbase can be one plan, $19 a month or $199 a year, without metering the things that generate traffic. Workflow runs aren't counted. Campaign sends aren't counted by Groundbase; the email goes through your own Resend account and the texts through your own Twilio. A pricing page with no meters is easier to offer when the bill underneath has few of them.

Why this website is on Vercel

Because it's a Next.js marketing site and a blog, which is the job Vercel is built for. Most pages are built ahead of time, a push deploys, and I didn't want to rebuild what Next.js and Vercel already do well. If Vercel had a bad day, you'd lose this site, which includes the help pages and a couple of the sign-up steps. The app, the API, your crons and your data would carry on, because none of them run there.

Where Workers is the wrong tool

  • The framework story is thinner. There's no Next.js equivalent for Workers. You write the routing yourself or use a light router. For an API that's fine. For a full-stack app with server components, you're rebuilding what Next.js gives you.
  • CPU time is limited. The free plan allows 10 ms of CPU per request (limits), which is too little for real work: a proper password hash takes longer than that on purpose. The paid plan defaults to 30 seconds and can go to 5 minutes. Sustained heavy work, like video encoding, still doesn't fit well.
  • A smaller community. Fewer answers, fewer tutorials, fewer people who already know it. That matters more for a team than for one person.
  • Observability is plain. I use wrangler tail more than any log explorer. And a warning logged by a cron every minute isn't monitoring, because nobody reads it. Anything that quietly breaks for a customer has to reach me some other way, and building that has been its own work.
  • One provider. The API, the crons, the queues and the files all depend on Cloudflare. If Cloudflare has a bad hour, so does Groundbase. I took that trade for a stack I can run alone.

What I'd tell another solo builder

Pick Workers for a backend that's mostly APIs, webhooks, crons and file serving, when you want a bill with few meters and you'd rather hold a small runtime in your head than a large framework.

Pick Vercel for a Next.js app where the framework does the heavy lifting, for a team that already knows it, and for a marketing site or a blog. That's why this one is there.

The right answer can differ between two halves of the same product. And whichever you pick, check what you've written about your own architecture now and then. Mine drifted from the truth without my noticing, which is why this post has a correction in it.


Questions about this one? Email me directly: blog-cloudflare@groundbasecrm.com — I read every one.

Built by a solo dev. Try it.

Start your 14-day trial →

More from the Pipeline

Notes

Why I'm not marketing Groundbase on LinkedIn

Most advice for small software products ends at "you should be on LinkedIn." I've decided not to market Gro…

Notes

Why I killed Groundbase's credits system and went BYO Twilio

Groundbase used to sell texting and calling as prepaid credits, at a markup. I removed the whole system and…

Comparisons

Free offline CRMs for Windows (2026): what's out there and what each one needs

Most "free CRMs" are a website with a free plan, a user limit and a contact cap. If you want one that runs …

Guides

Bill your hours without retyping them

Track time with a timer or log it after the fact, let the hourly rate remember itself, and put the unbilled…