Yes, Heroku is still a good platform for small teams that value deploy simplicity above cost and infrastructure control. For a growing team, the answer turns on two things: whether the bill scales acceptably against Heroku's published dyno and add-on pricing at your next headcount and traffic level, and whether you can accept never owning the underlying infrastructure. This post exists to help you check both before your renewal.
Here is why the timing matters. If your renewal is on your desk, the decision you are actually making is not "is Heroku good" in the abstract. It is "will this platform's cost curve still fit my business twelve months from now, at the dyno counts and add-on tiers I will need then, not the ones I have today." Every renewal cycle spent deferring that question compounds in two directions at once: the bill grows with each dyno and each database tier upgrade on Heroku's public pricing, and the eventual migration gets larger as your app surface grows. A two-service app is a bounded migration. A twelve-service app with three databases and a queue is a project.
So the argument of this post is not that Heroku is bad. It is that the decision should be made deliberately at renewal, with your own numbers, rather than by default. Below is the arithmetic to run, the roadmap signals to check yourself, and an honest accounting of what a migration costs and what it buys.
For the team that picked Heroku three or five years ago, the choice was correct. You got git-push deploys, managed databases, and zero infrastructure work at a stage when every engineering hour needed to go into the product. Nobody should feel foolish about that decision, and this post will not pretend otherwise.
The honest answer today splits by profile. Heroku remains a reasonable fit if your team is small, your traffic is modest and predictable, your dyno count is in the low single digits, and you have no compliance requirements that demand infrastructure in your own cloud account. At that profile, the premium you pay for the abstraction is small in absolute dollars and the alternative would cost you more in attention than it saves in cash.
The fit breaks when growth pushes you into higher dyno tiers, more services, and bigger add-on plans simultaneously, because those three multiply rather than add. It also breaks the moment a customer or auditor asks where your data lives and the only true answer is "in a platform vendor's cloud account, not ours." If either of those describes your next twelve months, the rest of this post is for you.
The thing Heroku got right, and the thing any replacement must preserve, is the workflow: a developer pushes code, the platform builds it, a release is created, and rollback is one command. That workflow is not the expensive part. The expensive part is the compute and data layer underneath it, priced at a per-dyno and per-tier premium over the raw cloud resources doing the work.
At small scale the premium is a rounding error. At growing-team scale it becomes a line item your CEO asks about, because it grows with usage in a way headcount does not. Three patterns show up repeatedly in teams at the $2M to $50M ARR range:
None of this is a criticism of the model. It is the model. A fully managed platform charges for absorbing infrastructure work, and the charge scales with usage. The question for a growing team is whether that trade still prices correctly at your next scale point. Which brings us to the arithmetic.
Everything below uses Heroku's published list prices at the time of writing. Heroku's pricing page lists Standard-1X dynos at $25 per month, Standard-2X at $50, and Performance-M at $250. Heroku Postgres Standard-0 is listed at $50 per month and Standard-2 at $200. Check the current pricing page before you rely on any figure here, and then redo this table with your own dyno counts. That is the whole point of the exercise: it is multiplication you can do yourself, not a benchmark you have to trust.
Consider a hypothetical growing team, and note that this is a worked illustration from list prices, not a customer result. Scenario A is where they are today. Scenario B is a plausible next scale point: traffic has roughly doubled, latency complaints pushed the web tier onto performance dynos, and the database moved up a plan.
| Component | Scenario A: today | Scenario B: next scale point |
|---|---|---|
| Web dynos | 4 x Standard-2X at $50 = $200/mo | 4 x Performance-M at $250 = $1,000/mo |
| Worker dynos | 2 x Standard-1X at $25 = $50/mo | 4 x Standard-2X at $50 = $200/mo |
| Postgres | Standard-0 = $50/mo | Standard-2 = $200/mo |
| Total | $300/mo, $3,600/yr | $1,400/mo, $16,800/yr |
Notice the shape, not just the totals. Traffic roughly doubled and the annual bill went up more than four and a half times, because scaling on a managed platform usually means moving up tiers, not just adding units. That nonlinearity is the thing to model before renewal. If your Scenario B lands under a few hundred dollars a month, renewing is defensible. If it lands in five figures annually and climbing, you are paying platform prices for infrastructure work you could increasingly own.
For contrast, Convox's own documentation publishes an estimate for a minimum production self-hosted Rack on AWS at roughly $228 or more per month in AWS infrastructure costs, itemized in the Cloud vs Rack comparison: three small EC2 instances, the EKS control plane fee, a load balancer, a NAT gateway, storage, and data transfer. Those are AWS list prices you pay AWS directly, and they scale with instance sizes you choose rather than with platform tiers. The comparison is not one-to-one, because owning an account carries responsibilities Heroku absorbs, and we will name those below. But the curve is different, and at growing-team scale the curve is what decides the budget conversation. When you are ready to look at the field of options rather than just the diagnosis, the Heroku alternatives overview lays out how they differ.
"Is Heroku dead" is a search a lot of engineering leaders run the week their renewal arrives, and the factual answer is no. Heroku operates, ships, and supports a large customer base. Treat anyone asserting its imminent demise as selling something, this post included, and verify the trajectory yourself instead. It takes about an hour:
The purpose of the exercise is not to catch Heroku declining. It is to establish, with your own eyes, whether the platform's direction of travel matches yours for the length of the contract you are about to sign. A growing team is signing up for where the platform will be in a year, not where it is today. If the check comes back reassuring, weight that in your decision. If it comes back ambiguous, weight that too.
The reason most growing teams stay on Heroku past the point where the math works is a reasonable fear: that leaving means adopting Kubernetes, hiring a platform engineer, and losing the deploy workflow that made the team fast. The design goal of Convox is that you keep the workflow and change only where it runs. A Convox Rack installs into your own AWS account and gives your team the same shape of experience: convox deploy to ship, convox env set for configuration, releases for every change, and convox releases rollback when something goes wrong. Kubernetes runs underneath, but nobody on your team writes Kubernetes manifests to ship code.
The mapping from Heroku concepts is direct and documented in the Heroku migration guide. Your Procfile process types become services in a single convox.yml, your database and cache add-ons become resources that inject the same style of connection URL your app already reads, and your scheduler jobs become timers. A typical Rails app on Heroku translates to something like this:
environment:
- SECRET_KEY_BASE
- RAILS_ENV=production
resources:
database:
type: postgres
cache:
type: redis
services:
web:
build: .
command: bundle exec rails server -b 0.0.0.0 -p 3000
port: 3000
resources:
- database
- cache
worker:
build: .
command: bundle exec sidekiq
resources:
- database
- cache
timers:
daily-report:
schedule: "0 6 * * *"
command: bin/rake reports:daily
service: worker
A resource named database injects DATABASE_URL into the services linked to it, so an app that reads DATABASE_URL on Heroku works without code changes. For production durability you can point the same resource definition at managed AWS RDS instead of a container, again without touching application code; the resource reference covers both modes. Environment variables work the way you expect, with values stored on releases rather than in the repo, per the environment documentation.
What changes is ownership and the shape of the bill. The infrastructure runs in your AWS account, your data never leaves it, and you pay AWS directly at AWS prices. Convox charges for the platform, not the infrastructure: there is no Convox markup on the AWS resources a self-hosted Rack uses. That means the cost levers Heroku's model keeps from you, such as reserved instances, savings plans, and instance-type choices, become yours as spend grows. It also means that if a HIPAA or SOC 2 requirement arrives next year, you are already running in an account you control rather than starting a second migration; Convox is compliance ready through the controls your own AWS account inherits. And because the platform runs on standard Kubernetes in your account, there is no equivalent of being locked inside a vendor's runtime. For the feature-level side-by-side, see the Convox vs Heroku comparison.
Migration is real work, and pretending otherwise would cost this post your trust. There are three concrete costs. First, Convox builds from a Dockerfile, so if your app deploys via Heroku buildpacks today, someone writes a Dockerfile per service; for most Rails, Node, Django, and similar apps this is bounded work with well-worn patterns, and the Dockerfile guide and example apps shorten it. Second, the datastore cutover: dump from Heroku Postgres, restore into your new resource, and do a final sync during the cutover window, exactly as the migration guide sequences it. Third, DNS moves last, after you have validated the app on its Convox-assigned hostname, which is what keeps the downtime window small.
Owning a cloud account also carries ongoing responsibilities Heroku absorbed: the AWS bill is yours to watch, account limits are yours to raise, and Rack version updates are yours to run, though they are designed for zero downtime and Convox manages the cluster machinery itself. The honest framing is this: the migration work is bounded and happens once, while the Heroku cost curve is unbounded and compounds every renewal. For a team whose Scenario B math came out ugly, that is the trade worth making. For a team whose math came out fine, it is not, and you should renew without guilt.
Before you sign, answer three questions with real numbers, not impressions. One: what is your projected twelve-month Heroku bill at next year's dyno counts and add-on tiers, computed from the public pricing page the way the table above was? Two: is there any compliance or data-residency requirement plausibly arriving in the next eighteen months that requires infrastructure in your own account? Three: how many engineering days would a bounded migration cost you, counting Dockerfiles, datastore cutover, and DNS, scoped honestly against the step-by-step migration guide?
If two of the three point toward staying, renew and revisit next cycle with the same discipline. If two of the three point away, do not attempt a big-bang move. Scope a single-app pilot: pick one service, write its Dockerfile, deploy it to a Rack in your AWS account, and validate the workflow end to end while Heroku keeps serving production. The pilot converts the scariest unknown, "will this stall our roadmap," into a measured number of engineering days before you commit to anything.
No. Heroku operates and ships today, and claims of its death are marketing, not fact. The useful question for a growing team is whether its pricing model and roadmap direction fit your next twelve months. Check the public changelog cadence, pricing history, and the maintenance status of the add-ons you depend on, then decide with evidence.
Yes, for early-stage teams with a handful of dynos, modest traffic, and no compliance requirements, Heroku remains a sensible choice. The fit weakens as service count, dyno tiers, and add-on plans grow together, because costs multiply across all three, and it breaks entirely once a customer or auditor requires infrastructure in your own cloud account.
Because scaling usually means moving up tiers rather than adding units, and each tier is a multiple of the last on the published price list. Performance dynos and higher database plans jump in steps, and a fully managed platform also keeps the cost levers, like reserved instances, that you would use on your own AWS account as spend grows.
It is bounded, not trivial. The work is writing a Dockerfile per service if you used buildpacks, translating your Procfile and add-ons into one convox.yml, cutting over the database with a dump and final sync, and moving DNS last after validating on a test hostname. The Convox migration guide sequences all of it so downtime stays minimal.
Yes. A Convox Rack installs into your AWS account and provides convox deploy, convox env set, releases, and one-command rollbacks on Kubernetes infrastructure you own. Your team keeps the push-and-ship workflow, your data stays in your account, and you pay AWS directly with no Convox markup on that infrastructure.
Run the three renewal questions against your own numbers this week, before the contract auto-renews for you. If the math points away from another year, start with the Heroku alternatives overview and scope a single-app pilot using the migration guide.
Create a free Convox account to stand up a Rack in your own AWS account, or talk to our team about an assisted migration if you would rather not run the pilot alone.