DEV Community

Cover image for Hetzner was cheaper at every size I tested and I still chose managed Postgres
Mirza Iqbal
Mirza Iqbal

Posted on

Hetzner was cheaper at every size I tested and I still chose managed Postgres

Twelve pricing tabs open. Neon, Hetzner, Supabase, Prisma, Scaleway, OVH.

My database is half a gigabyte. I was comparing ten-terabyte price curves.

At some point this week I typed the words "I am super lost here" about my own infrastructure. I advise companies on this exact class of decision. That sentence still came out of my hands.

If you have ever spent an evening deep in provider pricing pages for a workload that fits on a USB stick from 2009, this one is for you. All numbers below come from the live pricing pages as of July 2026. Rates move, so verify before you commit.

Three fears, all pointed at the wrong layers

I went in worried about getting attacked, running out of space, and being locked in.

All three dissolved under ten minutes of honest reading.

DDoS lands on the website edge, not the database. My site already sits behind Cloudflare and Vercel, and a database is never publicly exposed. Only the app talks to it. Whichever provider I picked, that attack surface stayed identical.

Here is the shape of the stack, and where each fear lives.

              MANAGED (what I run today)

  visitors ──> Cloudflare edge ──> Vercel app ──> managed Postgres
               [DDoS absorbed]     [stateless]    [never public,
                                                   app-only access,
                                                   provider patches,
                                                   provider backups,
                                                   provider on-call]

              SELF-HOSTED (the alternative I priced)

  visitors ──> Cloudflare edge ──> Vercel app ──> Hetzner CAX11
               [DDoS absorbed]     [stateless]    [Postgres :5432
                                                   firewalled to app,
                                                   SSH hardened,
                                                   fail2ban + auto-
                                                   patching = MINE]
                                                        │
                                     pg_dump every 6h   ▼
                                     encrypted ────> Cloudflare R2
                                                     [off-site copies]
Enter fullscreen mode Exit fullscreen mode

Same edge, same app, same attack surface. Everything in the right-hand box is what changes owners.

Storage was a rounding error. My data is 0.5 GB. Even the cheapest self-hosted box includes 40 GB, eighty times headroom before the first extra cent.

Lock-in was a phantom too. Managed Postgres is still stock Postgres. Exiting means a dump, a restore, and one connection string change in the deployment environment. Minutes of cutover, no rewrite anywhere.

Three fears, zero of them real. What remained was a variable I had never once billed for in my head.

Egress, the number that bites

Transfer out is where small databases produce surprising invoices, and it is where providers differ by orders of magnitude.

Option Egress included Overage Storage note
Neon Launch/Scale 500 GB/mo (raised from 100 GB, June 2026) $0.10/GB $0.35/GB-month, no base fee, usage metered hourly
Neon Free 5 GB/mo connections blocked until reset or upgrade 0.5 GB cap
Prisma Postgres unlimited, free on every plan none for egress, billed per operation instead operation quota is the real limiter
Supabase Pro 250 GB/mo $0.09/GB $25/mo base also bundles Auth, Storage, Realtime
Hetzner CAX11 (self-managed) 20 TB/mo ~€1/TB 40 GB NVMe included, volumes ~€0.057/GB
Scaleway / OVH managed bundled per instance tier varies fixed storage tiers per plan size

Twenty terabytes next to 250 gigabytes stops being a comparison and turns into a different sport.

One trap worth naming. Prisma removes egress from the bill entirely but meters queries instead, and blog traffic is exactly the pattern of many small frequent reads that makes per-operation billing hurt. Free egress can still be the expensive option for the wrong workload.

Storage cost from 1 GB to 10 TB

I priced the whole curve so the upper end stops being abstract.

Storage Neon ($0.35/GB-mo) Supabase Pro ($25 base, $0.125/GB over 8 GB) Hetzner (server ~€7/mo, volume €0.057/GB past 40 GB) Prisma (tier-based)
1 GB $0.35 $25 (included) €0 extra $10 Starter
10 GB $3.50 ~$25.25 €0 extra $10 Starter, at the limit
40 GB $14 ~$29 €0 extra, included $49 Pro
100 GB $35 ~$36.50 ~€3.42 extra custom tier
500 GB $175 ~$86.50 ~€33 total custom quote
1 TB ~$358 ~$152 ~€63 total custom quote
10 TB ~$3,584 ~$1,304 ~€590 total custom quote

Read the curve, not one row.

Neon is the steepest line. Simple to reason about, no volume discount ever, and by 1 TB it runs nearly six times Hetzner.

Supabase flattens better because the base fee absorbs early growth, then meters steadily.

Prisma moves in steps. Fine up to each plan limit, then a jump to the next tier's base fee, and past roughly 50 GB you leave published pricing entirely.

Hetzner stays cheapest at every single size I tested. At 40 GB, at 100, at one terabyte. I expected a break-even point somewhere. None exists. Self-hosting wins the spreadsheet from day one.

What it would cost ME, this month, per option

Abstract curves are one thing. Here is my actual workload priced. 0.5 GB of data, blog-shaped read traffic, egress nowhere near any allowance.

Option My realistic monthly bill What I own at 3am
Neon Free $0, I sit exactly at the 0.5 GB cap edge nothing, but one growth spurt blocks connections
Neon paid (pay-as-you-go) ~$0.18 storage + metered compute hours, realistically single-digit dollars nothing
Prisma Starter $10 flat nothing
Supabase Pro $25 flat, mostly paying for bundled services I would not use nothing
Hetzner CAX11 self-managed ~€5 to €8 all-in (server + snapshot backups) patching, hardening, backups, restores, incidents
Scaleway / OVH managed entry tiers vary, quote per tier before committing nothing

Transparency note. if you want to try Neon, this signup link is my referral and gives me a small credit. The comparison above stands either way, and Hetzner still wins the raw spreadsheet.

So the true spread at my size is roughly $0 to $25 a month. Which is exactly why the spreadsheet could not make this decision.

Why I still chose managed

Because a spreadsheet prices the server and never the pager.

Self-hosting a database means I own patching, hardening, backup scripts, health checks, the restore drill, and the incident at 3am when a runaway query eats the box. Every one of those is automatable, and I would enjoy building it. That is exactly the trap. I have a client engagement, a launch, and a talk to prepare. Cheap servers get expensive when they are bought with the hours I sell.

Managed means the provider owns the 3am page. That single sentence is the product. Everything else on the pricing page is decoration around it.

My honest math. a few euros per month separate the options at my size. One unbilled evening debugging Postgres memory settings costs more than a year of that gap.

What the backup plan looks like in real numbers

Whichever side you pick, write these numbers down before you need them.

Self-hosted, the setup I would run on Hetzner has two layers, because one layer only protects against half the disasters.

  • Provider snapshots of the whole server. daily, seven rolling copies, ~20 percent of the server price (about €1/mo here). Covers OS corruption and bad deploys.
  • Postgres dumps shipped OFF the server to object storage (R2 in my case). every 6 hours, encrypted. Daily kept 30 days, weekly kept 6 months, monthly kept a year. Covers the server itself being destroyed, which the on-server snapshot never can.
  BACKUP AND RESTORE PATH (self-hosted)

  Hetzner box ──[daily snapshot, 7 rolling]──> Hetzner backup space
       │
       └──[pg_dump every 6h, encrypted]──> R2 bucket
                                             ├─ daily,   kept 30 days
                                             ├─ weekly,  kept 6 months
                                             └─ monthly, kept 12 months

  DISASTER: box destroyed
  R2 latest dump ──> fresh box ──> restore ──> repoint conn string
  [ 15 to 30 minutes, scripted ]
Enter fullscreen mode Exit fullscreen mode

Translate that into the two numbers that matter.

  • Worst-case data loss (RPO). up to 6 hours, the dump interval. Tighten to 1 hour or continuous WAL streaming the day the site takes real transactional writes. For a content site, 6 hours is plenty.
  • Time back online (RTO). 15 to 30 minutes with a scripted restore. fresh box, latest dump, repoint the connection string.

Managed providers answer both numbers in their SLA instead. You are paying for the answers to already exist.

And a rule I hold either way. if you have never run the restore once, what you own is hope, and hope restores nothing.

When the database goes down anyway

Worth having answered before it happens, never during.

  1. A health check pings the DB every minute. Three consecutive failures fire an alert.
  2. Reads degrade before they die. Edge cache and static pages keep serving, only dynamic DB-backed paths fail.
  3. Restart comes before restore. Most outages are transient, an OOM, a runaway query, a bad migration.
  4. Restart fails, restore fires. Latest off-site dump onto a fresh box, the 15 to 30 minute path.
  5. Postmortem after recovery. Root cause, and whether it needs RAM, a query fix, or connection pooling.

On managed, items 1 through 4 collapse into "their on-call team handles it". You get notified instead of paged. That is the actual product you buy, named precisely.

One threshold ended the back-and-forth

I stopped trying to make an eternal choice and wrote a trigger instead.

Below 50 euros a month total, I stay managed and spend zero brain on infrastructure.

When egress or external traffic grows enough that the managed bill approaches that line, self-hosting earns its ops ownership and I revisit with the tables above.

That is the whole decision. One threshold, one revisit condition, written down. My paralysis came from treating a reversible, cheap-to-exit choice like a marriage. Stock Postgres on both sides makes switching a Tuesday afternoon, so choosing wrong costs nearly nothing, and a decision with near-zero switching cost deserves near-zero deliberation.

Your turn

Managed or self-hosted for your database, and what tipped it?

If this was useful

I work through this in public, the wins and the freezes both, mostly on LinkedIn and YouTube. If the real version of building in the open is useful to you, that is where it lives. Find me on X, GitHub, and the work at next8n.com.

Top comments (0)