Skip to content
inetGeek

Fly.io vs Heroku

A comparison of Fly.io and Heroku built from values read directly from each provider's own documentation, with the source recorded against every figure.

Updated 23 criteria compared

The short answer

Pick Fly.io if
Workloads that ship as Docker images and need placement in particular regions. Billing is purely usage-based with no plan tiers, which suits spiky or region-pinned traffic better than a flat monthly fee.
Pick Heroku if
Teams that want to deploy by pushing to Git and let the platform handle the runtime, with Postgres, a scheduler and Docker deploys available on the same platform.

10 sourced criteria separate them:

Pricing model
Fly.io: Usage-based, no compute plan tiers
Heroku: Usage-based on wall-clock time, prorated to the second
When you exceed a cap
Fly.io: No plan cap to exceed — Fly bills per second for provisioned resources. The only documented enforcement is unspecified automated scaling limits, which surface as an error message (platform-wide, all plans)
Heroku: Service sleeps: on the Eco plan ($5/month for a 1000 dyno-hour pool, the cheapest paid tier) exhausting the pool forces every Eco dyno on the account to sleep for the rest of the month, and extra hours cannot be bought
Memory (entry plan)
Fly.io: 256MB on shared-cpu-1x, the smallest Machine size ($2.02/month at the Amsterdam-region rate shown in the pricing table)
Heroku: 0.5 GB RAM on the Eco dyno ($5 flat/month, the cheapest paid dyno) and 0.5 GB on the Basic dyno ($7/month)
File or inode limit
Fly.io: 8 GB rootfs (deployed image) limit per Machine, platform-wide on all plans; exceeding it fails the image push at deploy time
Heroku: 1000 MB maximum compressed slug size, platform-wide on all plans; raisable via support ticket
Streaming response limit
Fly.io: No duration or size ceiling documented. Streaming works, but Fly Proxy buffers responses before compressing them, so progressive server-side rendering needs Content-Encoding: none set on those responses.
Heroku: Platform-wide (router): 30 seconds to send the first byte, then a rolling 55-second idle window — if no data is sent for 55 seconds the connection is terminated
Managed connection pooling
Fly.io: Supported
Heroku: Limited
Scheduled jobs
Fly.io: Limited
Heroku: Supported
Persistent storage
Fly.io: Supported
Heroku: Not supported
Scales to zero
Fly.io: Supported
Heroku: Limited
Regions
Fly.io: 18 regions
Heroku: 2 regions on the Common Runtime, which is what a standard dyno runs in: eu (Europe) and us (United States). A further 10 — Dublin, Frankfurt, London, Montreal, Mumbai, Oregon, Singapore, Sydney, Tokyo and Virginia — exist only in Private Spaces, an Enterprise product.

No affiliate links, sponsored placements or paid rankings appear on this site. Ordering follows the sourced data and the stated criteria.

01.

At a glance.

CriterionFly.ioHeroku
Pricing
Pricing modelUsage-based, no compute plan tiersUsage-based on wall-clock time, prorated to the second
When you exceed a capNo plan cap to exceed — Fly bills per second for provisioned resources. The only documented enforcement is unspecified automated scaling limits, which surface as an error message (platform-wide, all plans)Service sleeps: on the Eco plan ($5/month for a 1000 dyno-hour pool, the cheapest paid tier) exhausting the pool forces every Eco dyno on the account to sleep for the rest of the month, and extra hours cannot be bought
Limits
Memory (entry plan)
256MB on shared-cpu-1x, the smallest Machine size ($2.02/month at the Amsterdam-region rate shown in the pricing table)
0.5 GB RAM on the Eco dyno ($5 flat/month, the cheapest paid dyno) and 0.5 GB on the Basic dyno ($7/month)
File or inode limit8 GB rootfs (deployed image) limit per Machine, platform-wide on all plans; exceeding it fails the image push at deploy time1000 MB maximum compressed slug size, platform-wide on all plans; raisable via support ticket
Execution
Streaming response limit
No duration or size ceiling documented. Streaming works, but Fly Proxy buffers responses before compressing them, so progressive server-side rendering needs Content-Encoding: none set on those responses.
Platform-wide (router): 30 seconds to send the first byte, then a rolling 55-second idle window — if no data is sent for 55 seconds the connection is terminated
Managed connection pooling
Supported
Limited
Deployment
Docker deploymentSupportedSupported
Scheduled jobs
Limited
Supported
Infrastructure
Persistent storage
Supported
Not supported
Managed databasesSupportedSupported
Scales to zero
Supported
Limited
AutoscalingLimitedLimited
Regions
18 regions
2 regions on the Common Runtime, which is what a standard dyno runs in: eu (Europe) and us (United States). A further 10 — Dublin, Frankfurt, London, Montreal, Mumbai, Oregon, Singapore, Sydney, Tokyo and Virginia — exist only in Private Spaces, an Enterprise product.

Only criteria both providers publish appear here; a tinted cell marks a real difference. Criteria only one of them documents are listed below, and an absence there means we found no source — not that the feature is missing. How we source this.

The small bar above a value is inetGeek's own lean toward that side — computed from the same facts shown, never a number the provider published. See the picker below "The short answer" to weigh only the criteria you care about.

02.

Where they differ.

Pricing model

Fly.io
Usage-based, no compute plan tiers
Heroku
Usage-based on wall-clock time, prorated to the second
Sources (2) →
  • Fly.io pricing ↗

    “Plans get complicated, so we just charge based on usage. Billing is based on the resources provisioned for your apps, pro-rated for the time they are provisioned.”

    Read 2026-09-05 · official docs

  • Usage & Billing | Heroku Dev Center ↗

    “Heroku computes usage from wall-clock time, not CPU time. Any dynos scaled above 0 accrue usage, regardless of traffic or activity. Heroku prorates all costs to the second.”

    Read 2026-09-05 · official docs

When you exceed a cap

Fly.io
No plan cap to exceed — Fly bills per second for provisioned resources. The only documented enforcement is unspecified automated scaling limits, which surface as an error message (platform-wide, all plans)
Heroku
Service sleeps: on the Eco plan ($5/month for a 1000 dyno-hour pool, the cheapest paid tier) exhausting the pool forces every Eco dyno on the account to sleep for the rest of the month, and extra hours cannot be bought
Sources (2) →
  • Fly.io Resource Pricing · Fly Docs ↗

    “Organizations may be subject to automated scaling limits to prevent abuse or to help with capacity planning. Email the address in the error message if you run into such a limit and it's getting in your way.”

    Read 2026-09-05 · official pricing

  • Eco Dyno Hours | Heroku Dev Center ↗

    “When you use all your Eco dyno hours for a given month, all Eco dynos on your account are forced to sleep for the rest of the month. You can't purchase additional dyno hours.”

    Read 2026-09-05 · official docs

Memory (entry plan)

Fly.io

256MB on shared-cpu-1x, the smallest Machine size ($2.02/month at the Amsterdam-region rate shown in the pricing table)

Heroku

0.5 GB RAM on the Eco dyno ($5 flat/month, the cheapest paid dyno) and 0.5 GB on the Basic dyno ($7/month)

Sources (2) →

File or inode limit

Fly.io
8 GB rootfs (deployed image) limit per Machine, platform-wide on all plans; exceeding it fails the image push at deploy time
Heroku
1000 MB maximum compressed slug size, platform-wide on all plans; raisable via support ticket
Sources (2) →

Streaming response limit

Fly.io
No duration or size ceiling documented. Streaming works, but Fly Proxy buffers responses before compressing them, so progressive server-side rendering needs Content-Encoding: none set on those responses.
Heroku
Platform-wide (router): 30 seconds to send the first byte, then a rolling 55-second idle window — if no data is sent for 55 seconds the connection is terminated
Sources (2) →
  • Content Encoding — Fly Docs ↗

    “The proxy buffers responses before compressing them. That can break HTML streaming—e.g., progressive server-side rendering. To avoid buffering, disable compression by setting Content-Encoding: none for those responses”

    Read 2026-09-05 · official docs

  • Request Timeout | Heroku Dev Center ↗

    “Heroku supports HTTP features such as long-polling and streaming responses. An application has an initial 30 second window to respond with a single byte back to the client. However, each byte transmitted thereafter (either received from the client or sent by your application) resets a rolling 55 second window. If no data is sent during the 55 second window, the connection will be terminated.”

    Read 2026-09-05 · official docs

Managed connection pooling

Fly.io
Supported
Heroku
Limited
Sources (2) →
  • Cluster configuration options ↗

    “All Managed Postgres clusters come with PGBouncer for connection pooling, which helps manage database connections efficiently. You can configure how PGBouncer assigns connections to clients by changing the pool mode.”

    Read 2026-09-05 · official docs

  • Server-Side Connection Pooling for Heroku Postgres | Heroku Dev Center ↗

    “Server-side connection pooling is available for Standard, Premium, Private, and Shield-tier databases. [...] Server-side connection pooling isn't available for Essential-tier databases.”

    Read 2026-09-05 · official docs

Scheduled jobs

Fly.io
Limited
Heroku
Supported
Sources (2) →
  • fly machine run · Fly Docs ↗

    “Use the --schedule flag to set the Machine's config.schedule property, which starts the Machine on a fuzzy hourly, daily, weekly, or monthly cycle.”

    Read 2026-09-05 · official docs

  • Heroku Scheduler | Heroku Dev Center ↗

    “Scheduler is a free add-on for running jobs on your app at scheduled time intervals, much like cron in a traditional server environment.”

    Read 2026-09-05 · official docs

Persistent storage

Fly.io
Supported
Heroku
Not supported
Sources (2) →
  • Fly Volumes overview · Fly Docs ↗

    “Fly Volumes are local persistent storage for Fly Machines.”

    Read 2026-09-05 · official docs

  • Dynos (App Containers) | Heroku Dev Center ↗

    “Each dyno gets its own ephemeral filesystem, with a fresh copy of the most recently deployed code. During the dyno's lifetime, its running processes can use the filesystem as a temporary scratchpad, but no files that are written are visible to processes in any other dyno.”

    Read 2026-09-05 · official docs

Scales to zero

Fly.io
Supported
Heroku
Limited
Sources (2) →
  • Automatically stop and start Machines · Fly Docs ↗

    “Use autostop/autostart to automatically start and stop or suspend existing Machines based on incoming requests. [...] you don't pay for their CPU and RAM when they're in a stopped or suspended state.”

    Read 2026-09-05 · official docs

  • Eco Dyno Hours | Heroku Dev Center ↗

    “If an app has an Eco web dyno, and that dyno receives no web traffic in a 30-minute period, it sleeps. In addition to the web dyno sleeping, if you have a worker Eco dyno, it also sleeps. Eco web dynos do not consume Eco dyno hours while sleeping.”

    Read 2026-09-05 · official docs

Regions

Fly.io

18 regions

Heroku

2 regions on the Common Runtime, which is what a standard dyno runs in: eu (Europe) and us (United States). A further 10 — Dublin, Frankfurt, London, Montreal, Mumbai, Oregon, Singapore, Sydney, Tokyo and Virginia — exist only in Private Spaces, an Enterprise product.

Sources (2) →
  • Fly.io regions ↗

    “You can host your apps in any of the following regions — including ams (Amsterdam, Netherlands), nrt (Tokyo, Japan) and syd (Sydney, Australia).”

    Read 2026-09-05 · official docs

  • Regions | Heroku Dev Center ↗

    “eu Europe Common Runtime us United States Common Runtime dublin Dublin, Ireland Private Spaces frankfurt Frankfurt, Germany Private Spaces london London, United Kingdom Private Spaces montreal Montreal, Canada Private Spaces mumbai Mumbai, India Private Spaces oregon Oregon, United States Private Spaces singapore Singapore Private Spaces sydney Sydney, Australia Private Spaces tokyo Tokyo, Japan Private Spaces virginia Virginia, United States Private Spaces”

    Read 2026-09-05 · official docs

03.

Which should you choose?

Choose Fly.io if…

Workloads that ship as Docker images and need placement in particular regions. Billing is purely usage-based with no plan tiers, which suits spiky or region-pinned traffic better than a flat monthly fee.

Editorial · Palash Bagchi · approved

Choose Heroku if…

Teams that want to deploy by pushing to Git and let the platform handle the runtime, with Postgres, a scheduler and Docker deploys available on the same platform.

Editorial · Palash Bagchi · approved

Consider something else if…

  • Fly.io: You want a predictable flat bill rather than charges that track the resources provisioned for each app.
  • Heroku: The dyno filesystem is ephemeral, and a web process must respond within 30 seconds of receiving a request.
04.

Documented by only one.

These criteria are published by one provider and not the other. An absence here means we have not found a source, not that the feature is missing.

Entry paid planHeroku: $5 per month (Eco dynos plan, 1000 dyno hours shared across the account)
Egress over allowanceFly.io: $0.02 per GB (North America / Europe); $0.04 per GB (Asia Pacific / Oceania / South America); $0.12 per GB (Africa / India)
Sites or apps includedHeroku: 100 apps per account, platform-wide on all plans (Heroku Team 100, Enterprise Team 200)
Concurrent buildsHeroku: 10 concurrent builds for verified users without an established payment history; 300 for verified users with one (platform-wide, all plans)
Max request durationHeroku: 30 seconds (initial window for the web process to return response data)
CPU time limitFly.io: Platform-wide, per Machine size: shared vCPUs get a 5ms CPU quota per 80ms period (6.25%); performance vCPUs get the full 80ms. Quotas are shared across a Machine's vCPUs, and tasks are throttled for the rest of the period once the quota is reached.
Git deploymentHeroku: Supported
ContainersHeroku: Supported
Persistent processesHeroku: Supported
Edge networkFly.io: Limited
05.

Questions this comparison answers.

When you exceed a cap: Fly.io or Heroku?

Fly.io: No plan cap to exceed — Fly bills per second for provisioned resources. The only documented enforcement is unspecified automated scaling limits, which surface as an error message (platform-wide, all plans)

Heroku: Service sleeps: on the Eco plan ($5/month for a 1000 dyno-hour pool, the cheapest paid tier) exhausting the pool forces every Eco dyno on the account to sleep for the rest of the month, and extra hours cannot be bought

Should I choose Fly.io or Heroku?

Pick Fly.io if Workloads that ship as Docker images and need placement in particular regions. Billing is purely usage-based with no plan tiers, which suits spiky or region-pinned traffic better than a flat monthly fee.

Pick Heroku if Teams that want to deploy by pushing to Git and let the platform handle the runtime, with Postgres, a scheduler and Docker deploys available on the same platform.