# $900 Vercel Bill? How Surprise Invoices Happen

> Your $20 Vercel plan became $900 overnight. See the bandwidth math behind surprise invoices and the $5 VPS flat fix.

Source: https://boringpush.com/blog/vercel-surprise-bill-900-fix

## $20 in, $900 out, no warning

This is the post that shows up on r/nextjs every few weeks with a different number attached:

> "I was getting scraped unknowingly, and the moment I checked, my bill was $450 without ever getting a notification."

Another founder asks [WHEN does Vercel become expensive?](https://www.reddit.com/r/nextjs/comments/1fo5etb/when_does_vercel_become_expensive) and the top answer is blunt: serverless scales you to the equivalent of hundreds of $5 servers and sends you the bill.

A third thread — [Vercel Billing rant](https://www.reddit.com/r/nextjs/comments/1ijic43/vercel_billing_rant) — itemizes it line by line: 5.3M edge requests, 5M function invocations, and a Fast Origin Transfer line the poster never expected.

Nobody in those threads complains about the $20 seat. They complain that the bill arrives after the damage, built from four meters they never modeled.

If you run 2–5k daily visitors and ask [how fast does a bill really add up?](https://www.reddit.com/r/nextjs/comments/1oaezip/how_fast_does_a_vercel_bill_really_add_up), this post is the answer with the math shown.

## Four meters, one invoice

Vercel Pro (2026 public rates — verify current before you buy) bundles about 1TB of Fast Data Transfer, ~10M edge requests, ~1M function invocations, and a function-duration allowance into the base plan. Everything past the bundle meters separately:

| Meter | What triggers it | Included (Pro) | Overage |
|---|---|---|---|
| Fast Data Transfer | Bytes sent to visitors | ~1TB/mo | ~$0.15/GB |
| Edge Requests | Every request the edge handles, static files included | ~10M/mo | ~$2 per million |
| Function Invocations | Each serverless call | ~1M/mo | ~$0.60 per million |
| Function Duration | GB-hours your code runs | bundled allowance | per GB-hour past it |
| Image Optimization | next/image transforms + cache reads/writes | ~5k source images | per-thousand transforms |

Now run one realistic spike. A 4MB page hit 250,000 times in a month — bot traffic included, exactly the shape in the [Fast Origin Transfer thread](https://www.reddit.com/r/nextjs/comments/1ckmk09/fast_origin_transfer_will_let_my_vercel_bill):

- Data: 4MB × 250,000 = ~1TB. Right at the edge of the bundle — and that is before API responses, images, and JS bundles.
- Push it to 3TB total: (3,000 − 1,000GB) × $0.15 = **$300 in bandwidth overage alone**.
- Add 40M edge requests: (40M − 10M) × $2/M = **$60**.
- Total: ~$380 on top of the $20 seat, from one month. Double the traffic and you are past $700. Triple it and the $1,800/mo exits people post about stop sounding crazy.

Don't take the arithmetic on faith — drag your own numbers:

```calculator vercel-bill tb=3 edge=40 inv=5
```

Three details make it worse:

1. **Cache misses bill twice.** A 500KB API response served from cache costs one transfer. On a miss, the function-to-edge leg bills too — middleware in front doubles it again.
2. **ISR writes from throwaway values.** A timestamp or a random value in a revalidated component means the content hash never matches, so every revalidation writes. 1,440 revalidations a day is 43,000 writes a month from one page.
3. **Scrapers count.** Bots are edge requests and bandwidth like anyone else. The $450-bill poster found out from the invoice, not an alert.

None of this means Vercel is a scam. It means usage pricing punishes growth spikes — the exact moment a founder can least afford a surprise.

This post is the BoringPush playbook for that exact invoice: the math above, the flat-billing Next.js stack below.

## Flat billing on hardware you control

BoringPush runs the whole app — pages, API, database — on one $5/mo VPS (Hetzner, DigitalOcean, Linode) with SQLite on local NVMe. Same spike as above costs $0 extra because there is no per-GB meter.

Here is the shape.

**Step 1: Keep the database on the same box.** Point the app at local SQLite, not a cloud database. Queries run against local disk instead of crossing a network on every page. There is no connection pool to exhaust and no per-query meter. A network hop on every query is real latency on serverless, so measure your own pages before and after.

**Step 2: Ship with one command, no CI minutes.** Run `bp deploy`. It checks your code, builds it on your laptop and sends the result to the server, then waits for a health check. There is no build-minute meter and no per-seat deploy tax.

**Step 3: Close the ports scrapers abuse.** Cloudflare Tunnel takes public traffic through an outbound-only tunnel, so web ports on the box stay closed. Tailscale takes admin SSH through a private mesh, so port 22 is closed to the internet. A scraping bill gets much shorter when bots face Cloudflare's edge caching and your origin never answers a port scan.

The full walkthrough, including the firewall setup and the production gotchas (out-of-memory builds on small boxes, OAuth redirect mismatches), is in the BoringPush docs.

## What $5 actually covers

| Load | Vercel Pro shape | $5 VPS shape |
|---|---|---|
| 3TB transfer month | ~$20 seat + ~$300 overage | $5 flat, $0 overage |
| 40M edge requests | ~$60 overage line | Served by Nginx cache, $0 extra |
| 250k × 4MB bot spike | Bills like real users | Cloudflare absorbs + caches, origin sleeps |
| Cold starts | Possible on idle functions | None, the process stays up |
| 15s function timeout | Long exports die | Workers run as long as they need |

To be straight about it: you own the box. OS patches, disk space, and backups are yours — BoringPush takes daily database snapshots and can copy one off-site with `bp db backup --offsite`, but they still run on your machine.

That is the whole BoringPush bet: ship from anywhere — even your phone — on hardware you control.

## Know this first

- You do not have to leave Vercel. The same app runs there with a hosted database. You keep its dashboard and its meters.
- On a VPS, you own the box. Patches, disk space and backups are yours. BoringPush snapshots daily, and the rest is on you.
- Per-request pricing is gone. You are the on-call.
- The $5 buys one machine, not a global network.

## Why BoringPush is the way to do this

A flat bill, on purpose.

Pages, API and database run on one small server. `bp deploy` ships. Cloudflare absorbs the bots.

A traffic spike costs nothing extra. The price is the server, and the server is yours.

The math above is the reason. The flat bill is the fix.

## FAQ

### Do I have to leave Vercel to use BoringPush?
No. The same app runs on Vercel with a hosted database. This post is about the flat-bill path, not a forced migration.

### How do I know which meter burned me?
Open the Vercel dashboard → Usage, and read the four lines separately: Fast Data Transfer, Edge Requests, Function Invocations, Function Duration. In every thread linked above, transfer is the biggest line — model that one first.

### What traffic level is safe on Pro?
Under ~1TB/mo transfer and ~10M edge requests, you pay the seat. Past that, every extra terabyte is ~$150.

A 2–5k daily-visitor CRUD app with Cloudflare-cached images usually fits. Add heavy next/image transforms or uncached API responses and the margin shrinks fast.

### Does SQLite survive real production?
Yes, with the settings BoringPush ships: write-ahead logging, hourly log trimming and daily snapshots. A single small box is enough for most early products, though BoringPush does not publish a benchmark.

When you outgrow one box, switch to Supabase with no query rewrites.

### What if the VPS goes down while I sleep?
The process manager restarts the app, Cloudflare keeps serving cached pages, and BoringPush's Telegram or Discord incident alert reaches your phone. That alert path is covered in the fix-production-from-phone post.
