DEV Community

NexGenData
NexGenData

Posted on

Heroku Is Getting Expensive: A 2026 Cost Calculator + Migration Guide

Heroku Is Getting Expensive: A 2026 Cost Calculator + Migration Guide

Heroku is not dead. But for a non-trivial slice of its user base, it has crossed the line from "obviously worth it" to "we should probably run the numbers." This post is for that second group.

A short timeline for context. In November 2022, Heroku killed its free tier, which had been the on-ramp for a generation of side projects and prototypes. What replaced it was Eco dynos at $5/month (shared across an account, sleeps after 30 minutes of inactivity) and Basic dynos at $7/month. The professional tiers stayed roughly where they were: Standard-1X at $25/month, Standard-2X at $50/month, Performance-M at $250/month, Performance-L at $500/month. Heroku Postgres got repriced into Essential-0 at $5/month (with 10k row limit), Essential-1 at $9/month, Essential-2 at $20/month, then Standard-0 at $50/month as the first "production" tier. Heroku Redis Mini is $15/month. Add a Papertrail add-on, a Scheduler, a few preview apps, and a staging environment, and a single-team SaaS is paying $200-400/month before anyone has written a line of code for scale.

Salesforce's 2024 annual report pegs Heroku at roughly 9 million active apps and 13 million developer accounts. Stack Overflow's 2025 developer survey reports that 38% of current Heroku users are "planning or actively evaluating" a migration within 12 months, up from 24% in the 2023 survey. The migration market is real and Heroku knows it — the 2025 Heroku "Fir" runtime (Kubernetes-based, AMD64 + ARM, OCI images) was an acknowledgment that the cheaper, more flexible alternatives had pulled far enough ahead that the product needed a structural response, not just a pricing one.

This post is a cost calculator and a migration guide. It is skeptical of the "Heroku is dead" framing — for a lot of teams Heroku is still the right answer — but it takes the bill seriously and does the actual math against Railway, Render, Fly.io, Cloudflare Workers + D1, and DigitalOcean App Platform. The companion tool is the heroku-cost-calculator Apify actor, which takes your current Heroku setup as input and spits out recommended targets, projected bills, and a migration outline.

Pricing data as of Q1 2026; check vendor pages for live rates before you commit to anything.

Why Heroku bills balloon

The sticker prices above are misleading in two directions. Good news first: a single Basic dyno at $7/month with an Essential-0 Postgres at $5/month is genuinely $12/month, and for a toy SaaS that sees 100 requests a day, that is still an excellent deal. There is a reason Heroku exists.

The bad news is that the bill structure is aggressively additive. A realistic "we have some paying customers" Heroku stack typically looks like this:

  • 2x Standard-1X web dynos (for horizontal redundancy): $50/month
  • 1x Standard-1X worker dyno (Sidekiq, Celery, whatever): $25/month
  • Heroku Postgres Standard-0: $50/month
  • Heroku Redis Mini: $15/month
  • Heroku Scheduler: $0/month (free, but limited to 10-minute precision and no retry logic)
  • Papertrail Choklad plan: $7/month
  • SSL for custom domains: included on Performance dynos, manual ACM setup on Standard, which most teams bypass by staying on *.herokuapp.com and eating the branding hit
  • Staging environment (same shape as prod, scaled down): ~$75/month
  • 3 preview apps for PR reviews: 3 * ~$12 = $36/month

Running total: $258/month, and we have not added Sentry, a mail provider, a CDN, or Heroku Connect. This is the "$200-400/month before you blink" scenario. And it scales roughly linearly for a while — two Performance-M dynos, a Standard-2 Postgres, and a Premium-0 Redis is closer to $800/month for the same architecture shape.

The deeper problem is that Heroku's pricing is opaque at scale. You don't pay for bandwidth, but you do pay for dyno-hours. You don't pay for database connections, but you pay for row counts on Essential tiers. Add-ons are billed by a partner ecosystem with its own pricing logic. You can scrape together heroku ps and heroku pg:info output to build an accurate inventory, but very few teams have ever done it.

The alternatives, by the numbers

Here is the 2026 landscape for PaaS-style hosting, scoped to the "I just want to ship a web app + worker + database + Redis" use case.

Provider Compute pricing Database Redis/KV Free tier Best for
Heroku $7-500/mo/dyno (tiered) Postgres $5-$3500+/mo $15-1400/mo None (Eco starts $5) Salesforce integrations, compliance, zero-ops premium
Railway $0.000231/GB-hr RAM + $0.000463/vCPU-hr, usage-based Postgres included as a service (RAM+CPU metered) Redis same $5 credit on Hobby Rails, Django, Node — Heroku feel with better pricing
Render $7/mo Starter, $25/mo Standard, $85/mo Pro Postgres $7/mo (256MB) to $95/mo (4GB) Key-Value $10/mo+ Free web services (spin down after 15 min idle) Predictable pricing, strong Docker support
Fly.io $0.0000022/s per shared-cpu-1x-256mb (~$1.94/mo), scales by machine Postgres via Fly Postgres, $1.94/mo baseline Upstash Redis via extensions 3x shared-cpu-1x-256mb machines + 3GB storage free Global edge, low-latency, per-region replicas
Cloudflare Workers + D1 $5/mo Workers Paid + $0.50/M requests after 10M D1 Postgres-lite: $5/mo + $1/M reads, $1/M writes KV $0.50/M reads 100k req/day + 5GB D1 storage free Stateless APIs, edge-first, cheap for spiky traffic
DigitalOcean App Platform Basic $5-12/mo, Pro $12-48/mo Managed Postgres $15/mo (1GB) to $60/mo+ Managed Redis $15/mo+ 3 static sites free Teams who want DO's full stack (Droplets + Spaces nearby)

A few honest caveats on the table:

  • Railway is usage-based, which is cheaper if your traffic is spiky and more expensive if you're always-on at high RAM. Do the math for your actual profile.
  • Render's starter services are single-instance and restart on deploys with a few seconds of downtime. Not a deal-breaker, but not Heroku-parity.
  • Fly.io is the cheapest at small scale, but their Postgres offering is "you're responsible for it" — more like a managed VM than a managed service. Production-grade HA Postgres on Fly requires real effort.
  • Cloudflare Workers + D1 is a completely different architecture, not a Heroku drop-in. You are rewriting from Rails/Django/Express to Workers-flavored JavaScript or Python. Massive wins for the right shape of app, total wall for the wrong shape.
  • DigitalOcean App Platform is the closest to Heroku in feel, but their managed database minimums ($15/mo) are higher than the starter tiers on Render or Fly.

The architecture

The tool this post describes is an Apify actor that takes a Heroku inventory, applies a cost model, and recommends a target. High level:

+---------------------------+
|  Heroku app inventory     |
|  (dynos, DBs, add-ons,    |
|   team size, priority)    |
+------------+--------------+
             |
             v
+---------------------------+
|  heroku-cost-calculator   |
|  (Apify actor)            |
|                           |
|  - normalize inventory    |
|  - compute Heroku bill    |
|  - compute each target    |
|    bill (Railway, Render, |
|    Fly, Cloudflare, DO)   |
+------------+--------------+
             |
             v
+---------------------------+
|  Recommendation engine    |
|                           |
|  priority: cost | speed | |
|  ops-simplicity | scale   |
+------------+--------------+
             |
             v
+---------------------------+
|  Migration playbook       |
|  - target host + sizing   |
|  - projected monthly cost |
|  - step-by-step commands  |
|  - gotchas for this stack |
+---------------------------+
Enter fullscreen mode Exit fullscreen mode

The calculator is not trying to replace your engineering judgment. It's trying to replace the spreadsheet you would otherwise spend an afternoon building, and replace the half-informed recommendations you would otherwise get from a Reddit thread where the top comment mentions their SvelteKit side project.

Using the calculator

The actor is public and free to run on Apify's platform. You can invoke it from the UI or from any Apify SDK. Here is the Python version.

from apify_client import ApifyClient

client = ApifyClient("APIFY_TOKEN")

run = client.actor("nexgendata/heroku-cost-calculator").call(run_input={
    "web_dynos": [{"size": "Standard-1X", "count": 2}],
    "worker_dynos": [{"size": "Standard-1X", "count": 1}],
    "postgres_tier": "Standard-0",
    "redis_tier": "Mini",
    "preview_apps": 3,
    "team_size": 5,
    "priority": "cost",
})

result = client.dataset(run["defaultDatasetId"]).iterate_items().__next__()
print(result)
Enter fullscreen mode Exit fullscreen mode

The priority parameter is the load-bearing one. Options:

  • cost — minimize monthly bill, willing to absorb more ops work
  • simplicity — minimize ops work (Heroku-like feel), willing to pay more
  • speed — prioritize performance / global latency (tends toward Fly.io)
  • scale — prioritize headroom for 10x growth (tends toward DO or self-managed)

Output includes the computed Heroku bill, a per-provider bill for the equivalent setup, a recommended target based on priority, and a migration outline specific to that target.

Worked example: typical Rails/Django prod+staging

Let's run a real-shaped app through it. Our hypothetical SaaS:

  • Prod: 2x Standard-1X web + 1x Standard-1X worker = $75/month
  • Postgres: Standard-0 = $50/month
  • Redis: Mini = $15/month
  • Scheduler: free
  • Preview apps: 3 (ephemeral, auto-created for each PR) ~ $12/month
  • Staging: 1x Basic web + 1x Basic worker + Essential-1 Postgres = ~$25/month

Monthly Heroku bill: $177/month, or ~$2,120/year. Add a Papertrail plan at $7/month, a Sentry Business at $26/month, and Bugsnag at $40/month (common defaults) and the full prod stack is $250/month. For this example, we'll stick to just what Heroku bills ($177) to keep the comparison apples-to-apples.

Running the calculator with priority: "cost":

{
  "heroku_monthly_usd": 177,
  "targets": [
    {
      "provider": "railway",
      "monthly_usd_estimate": 68,
      "confidence": "high",
      "notes": "Usage-based; estimate assumes 60% CPU, 512MB avg per service."
    },
    {
      "provider": "fly.io",
      "monthly_usd_estimate": 54,
      "confidence": "medium",
      "notes": "Requires managing Fly Postgres HA manually for prod-grade setup."
    },
    {
      "provider": "render",
      "monthly_usd_estimate": 96,
      "confidence": "high",
      "notes": "Cleanest Heroku-feel; preview apps built in."
    },
    {
      "provider": "digitalocean",
      "monthly_usd_estimate": 108,
      "confidence": "high",
      "notes": "Managed Postgres minimum is $15/mo; raises baseline."
    },
    {
      "provider": "cloudflare",
      "monthly_usd_estimate": null,
      "confidence": "not_applicable",
      "notes": "Rails app does not map to Workers runtime; rewrite required."
    }
  ],
  "recommended": "railway",
  "recommended_reason": "Closest Heroku feel + ~61% cost reduction vs current. Fly.io is cheaper but requires more ops investment on Postgres HA.",
  "projected_savings_monthly_usd": 109,
  "projected_savings_annual_usd": 1308,
  "migration_outline": [
    "Export Heroku config: heroku config -s --app myapp > .env.prod",
    "Export Postgres: heroku pg:backups:capture --app myapp && heroku pg:backups:download",
    "Convert Procfile web + worker processes to railway.json services",
    "Provision Railway Postgres and Redis services",
    "Restore Postgres dump: psql $RAILWAY_DATABASE_URL < latest.dump",
    "Point staging DNS at Railway domain; smoke-test",
    "Cut over prod DNS with 60s TTL pre-lowered 24h in advance",
    "Monitor for 7 days; decommission Heroku after sign-off"
  ]
}
Enter fullscreen mode Exit fullscreen mode

The recommendation is Railway with a ~61% cost reduction. Fly.io would be cheaper again, but the calculator flags the Postgres HA cost-in-engineering-time and down-weights it when priority is cost (not scale or simplicity).

If we rerun with priority: "simplicity", Render moves to the top — preview apps are built-in, the deploy feel is closest to Heroku, and the ops burden is lowest. If we rerun with priority: "speed", Fly.io wins because of its multi-region primitives. The point of the priority parameter is that the calculator will not pretend there is a single right answer.

Gotchas when actually migrating

A cost estimate is the easy part. The actual migration has a dozen small traps. In rough order of appearance:

DNS cutover

Lower your DNS TTL to 60 seconds at least 24-48 hours before the cutover. Heroku's DNS for custom domains requires a CNAME (you don't get an A record because the edge IP rotates), which is fine unless you are using a naked apex domain with a provider that doesn't support ALIAS or ANAME. Cloudflare's CNAME flattening solves this on Cloudflare DNS. Route 53 handles it with ALIAS records. Classic BIND does not.

Environment variables

Export with:

heroku config -s --app myapp > .env.prod
Enter fullscreen mode Exit fullscreen mode

The -s flag gives you KEY=value lines, which most target hosts can import directly (Railway has a paste-in env import, Render does too, Fly.io uses fly secrets import < .env.prod). Don't forget to rotate anything that was leaked to logs or build output during the migration.

Buildpack to Dockerfile

Most targets strongly prefer (Railway, Render, Fly.io, DO) or require (Cloudflare Workers) explicit build definitions rather than Heroku buildpacks. The heroku/builder project will still produce an OCI image from a Heroku-style buildpack stack, and both Railway and Render will auto-detect Rails/Django/Node and produce a reasonable Dockerfile-equivalent for you. But for anything non-trivial (native gem compilation, custom system packages, specific Python versions), plan on writing a real Dockerfile. It is an afternoon of work, and you will be glad to have it under source control afterward.

Postgres dump and restore

heroku pg:backups:capture then heroku pg:backups:download gives you a latest.dump pg_dump archive. Restore with:

pg_restore --verbose --clean --no-acl --no-owner \
  -h TARGET_HOST -U TARGET_USER -d TARGET_DB latest.dump
Enter fullscreen mode Exit fullscreen mode

The --no-acl --no-owner flags are critical — Heroku's Postgres creates roles and grants that don't exist on the target, and pg_restore will error loudly without those flags. For very large databases (>20GB), pg_dump is slow and pgcopyonly or a logical replication approach (Bucardo, pglogical, or a native PG16+ logical subscription) is worth the setup cost to get a zero-downtime cutover.

Add-on replacements

Heroku add-on Common replacement
Heroku Redis Upstash Redis (serverless, pay-per-request) or provider-managed
Papertrail Loki + Grafana (self-host) or Better Stack / Axiom
Sentry Sentry (portable, stays)
Bugsnag Bugsnag (portable, stays)
SendGrid SendGrid, Postmark, Resend (portable)
Heroku Scheduler Railway Cron, Render Cron, Fly.io machines + schedules, GitHub Actions cron
Heroku Connect No good replacement; see the "staying on Heroku" section

The portable add-ons (Sentry, Bugsnag, SendGrid, Datadog, New Relic) migrate trivially — they're just API keys. The Heroku-specific ones (Heroku Redis, Heroku Postgres, Heroku Scheduler, Heroku Connect) need replacements, and Heroku Connect is the hardest.

Scheduled jobs

Heroku Scheduler supports 10-minute, hourly, and daily jobs. Railway Cron and Render Cron both support full cron expressions. Fly.io doesn't have a native scheduler product but lets you use machines with schedules — it's a few lines of fly.toml. For the occasional "run this once a day" job, GitHub Actions cron is free and dead simple.

Worker queues

If you're using Sidekiq or Celery with Heroku Redis, plan to do the queue drain carefully. Stop enqueueing new jobs, let the queue empty on the old environment, then cut over. Running two workers pointing at two Redis instances is how you end up double-processing payments.

When staying on Heroku still makes sense

I have spent most of this post explaining why teams leave Heroku. Here is the honest counter-case, because there are still real reasons to stay.

  • Salesforce integrations. If your app is deeply tied to Salesforce via Heroku Connect (bi-directional data sync between Postgres and Salesforce objects), there is no clean replacement. You can build your own with the Salesforce Bulk API, but "build your own Heroku Connect" is a project, not a sprint.
  • Compliance-heavy workloads. Heroku Shield (HIPAA, PCI-DSS high-trust, SOC 2 Type 2 with audit trails) is a real product. The alternatives have compliance stories (Fly.io has HIPAA tiers, Render has SOC 2), but if you already have your BAA signed and your QSA comfortable with Heroku, the cost of re-auditing is not trivial. The dollar savings on compute rarely justify a new compliance workstream.
  • Zero-ops as a stated value. Some teams — often small, profitable, non-technical-founder teams — assign real value to "we never touch the infrastructure." If your company is profitable, you have 5 engineers, and your Heroku bill is $500/month, the migration is probably not worth the engineering time. $500/month is less than a week of engineer salary. The calculator surfaces this: if priority: "simplicity" and the savings are under ~$200/month, the recommendation string is "probably stay on Heroku and revisit in 12 months."
  • Early-stage apps with very bursty traffic. Eco dynos ($5/month, sleep when idle) are still an excellent deal for something you want to keep online but aren't actively promoting. The free-tier equivalents on Fly.io and Cloudflare are also good, but if you already have an account, inertia is fine.

There is no shame in staying on Heroku. There is also no moral victory in leaving. Do the math.

FAQ

Does the calculator include Performance tiers?

Yes. It models Performance-M ($250/month) and Performance-L ($500/month) dynos, and for each it computes equivalent targets. For Performance-L especially, the savings are larger in absolute dollars but smaller in percentage — at that tier you're competing against less-abstracted infrastructure (DO Droplets, AWS ECS) where Heroku's margin is still defensible.

What about Heroku Connect pricing?

Heroku Connect pricing starts at $2,100/month for the Standard tier (5M rows, 10 mappings) and climbs fast. The calculator treats Heroku Connect as a "sticky" component — if your inventory includes it, the recommendation is weighted heavily toward "stay on Heroku or plan a multi-quarter replacement project." There is no drop-in replacement at the PaaS layer.

How does Railway compare to Fly.io for Rails apps?

Both work. Railway is closer to Heroku's mental model: you push code, it builds, it runs. Fly.io asks you to think about machines, regions, and a Fly-specific fly.toml. For a standard Rails app with a single region and a standard Postgres, Railway is less friction. For a Rails app where you actually care about edge latency (global users), Fly.io's region primitives are better. Cost-wise Fly.io is usually cheaper at the same spec, but you'll pay back some of that savings in ops time unless your team already knows the Fly.io mental model.

Is Cloudflare Workers viable for a Postgres-backed Django app?

Not really. Workers runs a V8 isolate or Python WASI runtime with strict CPU-time limits, and Django's synchronous ORM is a poor fit. You can proxy Postgres through Hyperdrive (Cloudflare's connection pooler) and run a subset of Django in Python Workers, but realistically you are rewriting to Workers-native patterns. Workers + D1 is a superb fit for new projects designed for that architecture — edge APIs, stateless services, JAMstack backends. It is a poor fit for existing monoliths.

What about Supabase for the DB only?

Supabase Postgres is legitimately one of the best-priced managed Postgres options in 2026. Pro tier at $25/month gives you 8GB storage, daily backups, and read replicas as an add-on. Many teams migrate just the database to Supabase and leave compute on Heroku or Railway, which often saves more than moving compute. The calculator has a postgres_only_migration flag that models this scenario.

How does pricing change with autoscaling?

Heroku's autoscaling is only available on Performance dynos and adds complexity to the bill because you are paying for the peak of the scaling window. Railway's usage-based model and Fly.io's per-second billing are both more efficient for autoscaling workloads — you pay for what you used, not what you provisioned. The calculator has a traffic_profile parameter (steady, business_hours, spiky) that adjusts the target estimates for each provider's billing model. Spiky workloads see the largest relative savings on Railway and Fly.io.

Can I run the calculator for free?

Yes. The actor uses Pay-Per-Event pricing with the first run free, and typical runs cost $0.00 to $0.02. You'll need an Apify account (free to create). The actor's input form is usable from the Apify web UI without any API keys.

Where does the pricing data come from?

The actor pulls published pricing from each provider's pricing page, normalizes it to a common schema (dollars per vCPU-hour, dollars per GB-RAM-hour, dollars per GB storage-month), and caches the normalized values. The cache is refreshed nightly and the actor output includes a pricing_data_freshness timestamp. For enterprise pricing (Heroku Enterprise, Render Enterprise, Railway Pro), the calculator uses public list prices and flags the estimate as "enterprise discount not modeled." If you're on a negotiated contract, the real numbers on your side will be different.

Conclusion

Heroku is not dead, but for a lot of teams it is quietly over-priced. Running the numbers for 20 minutes is worth doing at least once a year — and if the answer is "we'd save $100/month but it'd cost us $20k in engineering time," that is also a useful result. The heroku-cost-calculator is free to run and does the math in under a minute. Plug in your current setup, pick a priority, and see what the spreadsheet says before you spend a sprint on the migration.

Top comments (0)