DEV Community

Cover image for How to deploy a website at a low cost? How to choose between Vercel and Cloudflare?
jy H uang
jy H uang

Posted on

How to deploy a website at a low cost? How to choose between Vercel and Cloudflare?

Here is an idiomatic, developer-to-developer English translation that strips out the generic "AI tone" and keeps the practical, conversational style of an indie hacker:


It’s been just over a month since I officially kicked off my micro-SaaS tool project aimed at the global market.

Aside from building out features, I've spent a fair amount of time wrestling with infrastructure. For solo founders, keeping hosting costs as close to zero as possible, picking the right serverless provider, and avoiding surprise four-figure cloud bills are all things you want to think through before writing code.

Drawing from my own tech stack and real-world observations, here is a practical look at VPS vs. Serverless, why I lean toward Cloudflare over Vercel, and the best free-tier infrastructure available to bootstrapped devs today.


1. VPS vs. Serverless: Which One for Indie Projects?

When thinking about hosting, the classic developer playbook usually involves spinning up a VPS, installing a control panel (like aaPanel), setting up Nginx, configuring PM2 or systemd, and babysitting processes.

It’s a battle-tested and flexible approach. But for an early-stage side project, self-hosting eats into your most limited resource: time and mental bandwidth.

If your product is still in validation mode—low traffic, minimal background workloads—managed serverless platforms like Vercel or Cloudflare Workers should be your default.

Here is how the two approaches compare side by side:

Dimension VPS Serverless
Ops Burden Manual setup, Nginx configs, process management, security patches Fully managed; you focus almost entirely on application code
Scaling Manual vertical scaling, adding boxes, setting up load balancers Auto-scales instantly based on incoming traffic
Pricing Model Fixed monthly/annual cost; you pay even when idling Pay-per-use (requests/compute/bandwidth); virtually free at low volume
Cold Starts None (persistent running processes) Possible depending on the runtime (e.g., Node container vs. V8 isolates)
State & Storage Local filesystem, co-located SQLite/Postgres, Redis Stateless compute; requires managed DBs, KV stores, or S3-compatible object storage
Execution Time Uncapped; great for long-running jobs and heavy background tasks Strict CPU and execution timeouts per request
Runtime & Libs Full root access; install whatever OS packages or binaries you want Bound to supported runtimes, sandboxes, and platform-specific APIs
Networking Static public IPs, direct SSH, unrestricted outbound connections Dynamic egress IPs; static IPs or custom VPC networking often cost extra
Cost Curve Predictable flat fees; cheaper at steady, high traffic Dirt-cheap early on, but can spike fast with unoptimized loops or bandwidth spikes

For anyone starting out solo, I strongly recommend going Serverless first.

Developer time is your most expensive asset. Instead of spending your weekends configuring firewalls and updating OS packages, focus on shipping, talking to users, and finding product-market fit. Once you have sustainable traffic and clear infrastructure demands, you can always migrate.

Of course, serverless has hard limits. If your app needs persistent worker daemons, heavy audio/video transcoding, CPU-intensive background jobs, or custom native binaries, a VPS, container host (like Railway or Fly.io), or a dedicated job queue will be a much better fit.


2. Serverless Footguns to Watch Out For

Serverless makes deployment trivial, but the runtime environments vary significantly across platforms.

Take Vercel and Cloudflare Workers:

  • Vercel Functions run in a standard Node.js environment, but still impose limits on execution time, memory, CPU, and payload sizes.
  • Cloudflare Workers run on lightweight V8 isolates. They use their own Web Standards runtime APIs and rely on a compatibility layer to emulate a subset of Node.js.

In practice, code that runs fine locally in Node might crash immediately when pushed to Cloudflare Workers. Anything relying on native C++ bindings, child processes, direct filesystem access, or unsupported Node built-ins will bite you.

If you plan on using Cloudflare Workers, skim these docs first:

You don't need to memorize every quirk. Instead, add these platform constraints directly into your project’s AGENTS.md (or AI system prompts / rules). That way, coding assistants like Cursor won't generate code incompatible with your runtime.

A few practical rules to bake in:

  • Target deployment: Cloudflare Workers (V8 isolate runtime, not full Node.js).
  • Stick to Web Standard APIs and verified isolate-compatible packages.
  • Always verify compatibility before introducing Node built-ins, filesystem calls, or native modules.
  • Check CPU execution limits and timeouts before writing asynchronous or background tasks.
  • Run a build and dry-run smoke test immediately after changing deployment configs.

Having these boundaries explicitly written down eliminates hours of debugging hallucinated, incompatible code generated by LLMs.


3. Dodging the "Surprise Serverless Bill"

A viral post recently surfaced showing a developer getting hit with a massive cloud bill out of nowhere:

https://x.com/shmily7/status/2107481028726251762

Other seasoned devs have shared similar horror stories and preventative tips:

https://x.com/mcwangcn/status/2104926120457953565

With "Vibe Coding" becoming second nature, one overlooked risk is that AI often writes broken polling, retry, or recursive logic. Left unchecked, this can hammer your endpoints endlessly and burn through your compute quotas and API credits before you notice.

Common culprits:

  • setInterval polling an API indefinitely without an exit condition.
  • Retrying failed requests instantly with no exponential backoff or retry caps.
  • React components re-mounting repeatedly, spawning duplicate polling loops in the background.
  • Webhook failures triggering infinite retry cascades.
  • Background workers getting stuck processing the same payload in a loop.
  • Aggressive client-side polling that stays active even after users switch tabs.

Individually, these look minor. But when paired with pay-per-request pricing, a bit of traffic, or upstream AI API costs, your bill can spiral very fast.

Here is my pre-launch checklist to keep bills under control:

1. Have AI Audit Your Loops and Workflows

Don't just ask the AI to implement the feature—explicitly ask it to look for edge cases in retries, recursion, loops, and background tasks. Verify that every poll has a teardown, every retry has backoff and limits, and requests are properly debounced.

2. Set Up Hard Budget Alerts

Configure spending alerts across your cloud hosts, managed databases, object stores, and third-party AI providers. Keep in mind that many platforms only notify you when a budget is crossed rather than cutting off the service. Alerts alone won't save you if your logic goes into an infinite loop overnight.

3. Track Usage Metrics, Not Just Vanity Traffic

Keep an eye on actual operational metrics: CPU execution time, function invocations, bandwidth egress, database row reads/writes, and storage operations. If you see a spike out of proportion with visitor growth, track down the offending endpoint immediately.

4. Have an Exit Plan Ready

If your traffic takes off to the point where serverless unit economics stop making sense, or you outgrow runtime constraints, be ready to migrate to a VPS or container setup.

With AI tools, refactoring deployment pipelines and writing migration scripts is faster than ever. But you still need to test thoroughly—especially around database connections, file uploads, cron jobs, environment variables, and webhook handlers.

The goal of frugal infrastructure isn't just cutting costs today—it’s making sure your resource usage scales predictably with your actual business.


4. Vercel vs. Cloudflare: Why I Lean Toward Cloudflare

Many developers spin up a Next.js template by default and deploy it straight to Vercel. It’s convenient, frictionless, and great for getting started.

Personally, though, I've grown weary of both the Next.js developer experience and Vercel’s vendor lock-in.

If you're curious about this perspective, this post breaks down the vendor dynamics well:

The Hypocrisy of Vercel

My preferred stack today is TanStack Start, built on top of Vite. Now that TanStack Start has hit 1.0, the developer experience feels so much cleaner and lighter.

Anyone who has worked on a non-trivial project with Next.js knows the pain of the dev server crawling and devouring all your RAM. No matter how powerful your laptop is, it somehow finds a way to peg your memory. The community has brought this up for years, and while recent releases mention improvements, I honestly have zero desire to go back.

Here is a quick look at how the free tiers compare:

(Note: Quotas are based on current official documentation as a general point of reference. Platform limits change over time, so always verify on their official pricing pages before committing.)

4.1 Vercel Hobby (Free Tier)

Resource Allowance Reference
Fast Data Transfer (CDN Egress) 100 GB/month
Fast Origin Transfer 10 GB/month
Function Invocations 1,000,000 requests/month
Active CPU Time 4 hours/month
Provisioned Memory 360 GB-hours/month
Image Optimization 5,000 source images/month
Edge Image Caching (Read/Write) 300K / 100K ops/month
Build Limits Max 45 mins/deployment; up to 100 deployments/day
Function Specs Up to 2 GB memory / 1 vCPU; up to 300s timeout (depending on config)

Vercel shines with its Next.js ergonomics, preview environments, and seamless Git workflow.

However, for solo builders, it’s not just the 1M invocation cap you need to monitor—active CPU time, origin egress, and image optimization overages can trigger charges unexpectedly even if you think you're well within the free tier.

Docs: Vercel Pricing

4.2 Cloudflare (Free Tier)

Resource Allowance Reference
Workers Invocations 100,000 requests/day (~3M requests/month)
CPU Time 10 ms per invocation
Static Assets (Workers Assets) Free and unmetered (per platform guidelines)
KV Storage 100,000 reads/day; 1 GB storage
D1 Database Daily read/write row quotas apply; storage included per plan rules
Durable Objects Free request/compute allowances available depending on storage setup
R2 Object Storage 10 GB storage; 1M Class A ops/mo; 10M Class B ops/mo; Zero egress fees
Hyperdrive Free query pooling tiers
Queues Free monthly message operation limits

Cloudflare’s biggest advantage is the breadth of its ecosystem. Beyond compute (Workers), you get out-of-the-box object storage, databases, edge key-value stores, and message queues on a unified global edge.

R2 in particular is a game-changer for media-heavy tool sites. Free egress means you aren't penalized simply because users are downloading audio, video, or image assets from your storage.

One caveat: Cloudflare manages products under separate billing line items. A generous free tier on Workers doesn't automatically mean unlimited DB or KV usage. Track your CPU time, operations, and row limits independently.

Docs:


5. Beyond Hosting: Essential Free Tools

Hosting is only half the battle. Several third-party services offer generous free tiers that allow indie hackers to build a solid operational foundation on day one:

Tool Core Use Case
Sentry Exception monitoring, error stack traces, and performance bottlenecks
Google Analytics 4 Traffic sources, user acquisition, and conversion funnels
Microsoft Clarity Free session replay, heatmaps, and UX interaction tracking

For a newly launched tool site, here is the order I recommend integrating them:

  1. Error Tracking: Catch runtime crashes before users bother reporting them.
  2. Product Analytics: Understand traffic sources, drop-offs, and which features actually get used.
  3. Billing Alerts: Watch third-party AI APIs and compute limits like a hawk.
  4. CI/CD Automation: Use GitHub Actions so deploying updates is a simple git push.

You don’t need to set all of these up on day one. Hook up the pieces that directly safeguard stability and inform product decisions first, then layer on the rest as you grow.


6. Wrap-up: My Reusable SaaS Starter

Every time you kick off a new project, setting up the same plumbing—auth, error tracking, analytics, styling, and deployments—gets tedious.

To cut down on boilerplate fatigue, I packaged my go-to setup into an open-source starter repo:

It reflects the stack I personally enjoy building with, and serves as a clean starting point for quick turnaround MVPs. You can easily clone it and have an AI agent adapt it to your preferred services.

Every solo developer eventually benefits from having their own starter kit. Standardizing the repetitive grunt work early frees up your time to focus on the only thing that actually matters: building a product people want.

Top comments (0)