A production Node.js app with Postgres costs $128 a month on Heroku and about $10 on Hetzner. Same container, same workload, a roughly 13x delta — and most migration writeups still undercount it, because the gap isn't in any single line item. It's in three of them at once: per-dyno compute that multiplies with every process type, a managed database tier jump from $20 to $50 the moment you want production guarantees, and a bandwidth story where one platform gives you 2TB with a ceiling and the other gives you 20TB with a meter that charges roughly €1 per terabyte after that.
Below: the full receipt for each side, the egress math at four traffic levels, and the honest counter-case — the team profile for which Heroku's pricing is still the rational choice.
The two bills, side by side
The workload: a typical small-production Node.js API — two web processes, one background worker, one Postgres database, a small Redis for queues and caching. Nothing exotic; this is the shape of thousands of Heroku apps.
| Line item | Heroku (2026 prices) | Hetzner (CX32, EU) |
|---|---|---|
| Compute | 2x Standard-1X web ($25 ea) + 1x Standard-1X worker ($25) = $75 | 1x CX32, 4 vCPU / 8 GB RAM = ~$9 |
| Postgres | Standard-0, 64 GB, HA failover = $50 | Self-managed Postgres in a container = $0 |
| Redis | Key-Value Store Mini = $3 | Self-managed Valkey/Redis in a container = $0 |
| Bandwidth (up to 2 TB) | Included = $0 | Included (20 TB) = $0 |
| Backups/snapshots | Included in Standard-0 = $0 | 1 snapshot, |
| Monthly total | $128 | ~$10 |
That is the whole argument in one table: $128 versus ~$10, a roughly 13x delta for the same running workload. Everything below is the receipt — where each line comes from, where the math changes with scale, and where it stops favoring Hetzner.
The Heroku bill, line by line
Compute: $75, and it multiplies. A Standard-1X dyno costs $25 a month for 512 MB of RAM. The dyno is Heroku's unit of billing, and every process type is billed separately: two web dynos for basic redundancy plus one worker is three dyno charges before you've served a single request. Add a staging environment and you've doubled it again. The Eco plan ($5 for a shared 1,000-hour pool) and Basic ($7, always-on) exist, but both cap at 512 MB without horizontal scaling — fine for side projects, not the production shape we're pricing.
Note the RAM asymmetry, because it matters for the other side of this comparison: $75 of Heroku compute buys you 1.5 GB of RAM total across three dynos. Keep that number in mind.
Postgres: $50, with a cliff at $20. Heroku's current Postgres tiers run Essential-0 at $5 (1 GB), Essential-1 at $9 (10 GB), Essential-2 at $20 (32 GB), then Standard-0 at $50 (64 GB). The older Mini/Basic plans are deprecated. The jump that stings is Essential-2 to Standard-0: $20 to $50, a 2.5x step for the tier where production features — high availability with automatic failover, point-in-time recovery, larger connection headroom — actually live. A production workload with any availability story lands on Standard-0, which is why $50, not $5 or $20, is the honest Postgres line for this comparison.
Redis: $3, the cheapest line on the bill. The Key-Value Store Mini plan at $3 a month covers queue and cache duty for a workload this size. Production-grade Redis tiers start at $15 and climb, but nothing about this workload forces that upgrade.
Bandwidth: $0, with a ceiling instead of a meter. Heroku includes 2 TB of data transfer per app per month and does not publish a per-gigabyte overage price. There is no line where egress shows up as dollars — instead, sustained traffic past the fair-use allowance becomes a conversation with Heroku about your architecture, which in practice means a CDN in front, a move to larger dynos, or, at real scale, Private Spaces pricing. The egress cost on Heroku is $0 right up until it becomes a forcing function.
Heroku total: $128 a month, of which $125 is compute plus database. Every additional process type, every staging copy, every dyno-size bump scales that number linearly — there is no bin-packing, no shared headroom, no volume discount at this tier.
The Hetzner bill, line by line
Compute: ~$9, and it doesn't multiply. A CX32 cloud server — 4 shared vCPUs, 8 GB of RAM, 80 GB of NVMe — lists at roughly €8.50 a month, about $9. The smaller CX22 (2 vCPU, 4 GB) is roughly €4.50, about $5. Run the web processes, the worker, Postgres, and Redis as containers on the one box — via Docker Compose, Dokploy, Coolify, or a single-node k3s — and the compute line stops there. No per-process charge, no staging multiplier (a second CX22 for staging adds $5, not a second full bill).
Now recall the RAM asymmetry: $75 of Heroku compute bought 1.5 GB across three dynos. The $9 CX32 holds 8 GB — more than 5x the memory at one-eighth the price. The entire Heroku compute footprint for this workload fits inside a single CX22 with room to spare. This is the line where the "3-7x multiplier" migration writeups cite actually understates the gap: on raw compute alone it is 8-15x, depending on which CX size you pick.
Postgres and Redis: $0 in license, nonzero in ops time. This is the line where honest accounting matters. Self-managed Postgres costs nothing in software and roughly an afternoon of setup (automated backups to object storage, a restore drill, version-pinned image) plus ongoing patching. Valued at a fully loaded engineering hour, even two hours a month of database care dwarfs the $9 server. The Hetzner bill is $10 only if your team's ops time is already paid for and already allocated — for a team with zero ops capacity, that line is not $0, it is a hiring plan. More on that in the counter-case below.
Backups: ~$1. A CX32 snapshot runs about €0.01 per GB per month — under a euro for a full-box image. Off-box Postgres dumps to Hetzner's object storage (base €6.49 a month for ~1 TB including ~1 TB egress, at post-June-2026 prices) only make sense once you outgrow what fits in a snapshot; at this workload size, snapshots plus a cron job pushing pg_dump to cheap object storage round to about a dollar.
Bandwidth: $0, with 10x the headroom. Every CX server in an EU region includes 20 TB of monthly traffic, pooled across all servers in the project, with overage at roughly €1 per TB (about a tenth of a cent per GB). Note the regional caveat: US-region Hetzner servers include far less (around 1 TB depending on tier), so the 20 TB figure is a EU-region story. For this workload at any sane traffic level, the bandwidth line is $0 with a ceiling ten times Heroku's.
Hetzner total: ~$10 a month, of which the only recurring charge that scales with anything is snapshot storage and, past 20 TB, bandwidth at €1/TB.
The egress math at 100 GB, 1 TB, 5 TB, and 20 TB
Egress is where migration writeups most often hand-wave, so here is the sensitivity table. Monthly outbound transfer down the left; what each platform charges (or forces) across the top. A hyperscaler column at $0.09/GB — the standard AWS/GCP egress neighborhood — anchors what metered bandwidth normally costs.
| Monthly egress | Heroku | Hetzner CX (EU) | Hyperscaler @ $0.09/GB |
|---|---|---|---|
| 100 GB | $0 (included) | $0 (included) | ~$9 |
| 1 TB | $0 (included) | $0 (included) | ~$92 |
| 2 TB | $0 — at the fair-use ceiling | $0 (included) | ~$184 |
| 5 TB | $0 metered, but past policy: CDN/upgrade conversation | $0 (included) | ~$460 |
| 20 TB | Not viable on standard plans | $0 (included) | ~$1,840 |
| 25 TB | Not viable on standard plans | ~€5 overage | ~$2,300 |
Three things fall out of this table. First, below 2 TB the egress line is $0 everywhere that matters — neither Heroku nor Hetzner charges this workload a cent for bandwidth, and the whole 13x delta comes from compute and database. Teams that lead their migration pitch with egress have the mechanism wrong at small scale.
Second, the platforms diverge exactly where growth lives: between 2 TB and 20 TB, Heroku's answer is architectural (add a CDN, split traffic, upgrade plans) while Hetzner's answer is nothing — the traffic is already paid for. A media-heavy app, an API with large payloads, or anything serving model artifacts crosses 2 TB long before it feels "big."
Third, Hetzner's overage rate reframes what bandwidth is worth: at ~€1/TB versus ~$92/TB at hyperscaler rates, 20 TB of egress costs less than a dollar-equivalent fudge on Hetzner and nearly two grand on AWS. The 3-7x multiplier this space likes to quote is a blended average; on the egress line alone, past the included allowances, it is closer to 90x.
Where Heroku still wins
A 13x bill delta is not a 13x value delta, and the honest version of this post names exactly who should keep paying it.
Teams with zero ops capacity. The Hetzner $10 assumes someone patches Postgres, rotates credentials, tests restores, watches disk, and wakes up when the box does something strange at 3 AM. Heroku Standard-0's $50 includes automated failover, point-in-time recovery, and a support contract — bought sleep, not just storage. If your team has no one who can own a database, the $118 monthly "savings" is negative the moment one incident eats an afternoon.
Review apps and pipeline velocity. Heroku's per-dyno model is also its deployment model: git push, review apps per pull request, one-click rollbacks, and an add-on marketplace that provisions datastores in seconds. Reproducing that on Hetzner means installing and maintaining Dokploy, Coolify, or a self-hosted PaaS layer of your own — all good tools, all yours to operate. For a team shipping features daily with no platform engineer, Heroku's premium is a headcount substitution, and headcount costs more than $128 a month.
Compliance and audit surface. SOC 2 evidence, data-residency controls, and vendor-security questionnaires are dramatically cheaper to answer when the database is someone else's managed service with published certifications. Regulated teams often find Heroku's bill is the smallest line in their compliance budget.
Spiky, short-lived, or tiny workloads. A prototype that needs to exist this afternoon, a webhook receiver, a staging environment that lives for a week — Heroku's per-second-billed dynos (Standard-1X at ~$0.03/hr) and $5-9 Essential Postgres tiers price these at single dollars with zero setup. The Hetzner advantage compounds with steady-state production traffic; it inverts for ephemera.
The decision rule is simple: if an engineer-hour of your team's time is worth more than the monthly delta, and the migration would cost more than a few such hours plus ongoing care, Heroku wins. At $118 a month of delta, that bar clears almost immediately for funded teams — which is precisely why Heroku still has customers, and why "just move to Hetzner" is advice, not a strategy.
The gap is a PaaS-shaped hole
The real lesson of the two bills is not that one vendor is greedy and the other is generous. Heroku charges for operations labor bundled as a product; Hetzner charges for raw machines with operations explicitly excluded. The $118 gap is the market price of the missing layer: a Heroku-grade deployment experience running on Hetzner-grade hardware.
That layer is exactly what the self-hosted PaaS wave — Dokploy, Coolify, CapRover, and the Cluster API-based platforms growing up beneath them — is trying to commoditize. Every team that migrates off Heroku re-implements some slice of it by hand; the platforms that survive will be the ones that make the $10 bill come with the $128 experience. Until then, run the numbers for your own workload, be honest about the ops line, and pick the bill you can actually afford to pay — in dollars or in attention.
Running the migration math for your own team? Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.



